Great question! Let’s break down how multithreading works in Java, why it’s important, and how you can use it.
☕️ What is Multithreading?
✅ Multithreading is the ability to run multiple parts (threads) of a program concurrently.
✅ Each thread is a separate path of execution within a program.
✅ Threads share the same memory space (heap), but each thread gets its own stack.
🚀 Why Multithreading?
✅ Better performance — You can utilize multi-core CPUs more efficiently.
✅ Responsive programs — For example, in a GUI app, you can run background tasks (like downloading a file) without freezing the UI.
✅ Parallel processing — Break large tasks into smaller independent pieces and run them in parallel (e.g., in web servers handling many requests).
🧵 How to Create Threads in Java
✅ Option 1: Extend Thread
class
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread running...");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // starts a new thread
}
}
✅ Option 2: Implement Runnable
interface (recommended)
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread running...");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
✅ Option 3: Use Lambda (Java 8+)
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("Thread running..."));
thread.start();
}
}
🔄 Thread Lifecycle
State | Description |
---|---|
NEW | Created but not started (new Thread() ). |
RUNNABLE | Running or ready to run (after start() ). |
BLOCKED | Waiting to acquire a lock. |
WAITING | Waiting indefinitely for another thread’s signal. |
TIMED_WAITING | Waiting for a specific time (e.g., sleep(1000) ). |
TERMINATED | Completed or stopped by exception. |
⚙️ Synchronization (Thread Safety)
Since threads share memory, data races can occur if multiple threads access/modify the same object simultaneously. To avoid this, Java provides:
✅ synchronized
keyword (lock object/monitor)
synchronized void criticalSection() {
// only one thread at a time can enter here
}
✅ Locks (ReentrantLock
) ✅ Atomic variables (AtomicInteger
) ✅ Concurrent collections (ConcurrentHashMap
)
🏗️ Executor Framework (Better Thread Management)
Instead of creating and managing threads manually, use:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> System.out.println("Task running"));
executor.shutdown();
✅ Better performance (thread pooling)
✅ Automatic thread reuse
✅ Handles task queuing