Multithreading is a powerful feature in Java that allows concurrent execution of two or more parts of a program. It plays a crucial role in performance-critical applications such as web servers, real-time systems, gaming engines, and high-throughput services.
In the modern computing landscape where multi-core processors are the norm, mastering multithreading is essential for building responsive and scalable applications.
What is Multithreading?
Multithreading refers to the concurrent execution of two or more threads (smaller units of a process). It enables a program to perform multiple operations simultaneously, utilizing CPU cores efficiently.
Real-world analogy
Think of a thread pool like a team of factory workers — each worker (thread) is assigned a task. Once completed, they take the next one from the queue.
Java Threading API
Core classes and interfaces
Thread
Runnable
Callable<V>
(returns result, supports checked exceptions)
Creating threads
public class MyThread extends Thread {
public void run() {
System.out.println("Running in MyThread");
}
}
public class MyRunnable implements Runnable {
public void run() {
System.out.println("Running in MyRunnable");
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(() -> System.out.println("Running in thread pool"));
Thread Lifecycle and States
NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED
Key methods
start()
vsrun()
join()
sleep(ms)
yield()
interrupt()
Memory Model and Visibility
- Java Memory Model (JMM) defines how threads interact through memory
volatile
ensures visibility (but not atomicity)synchronized
ensures mutual exclusion and memory visibility
Thread Coordination
wait()
,notify()
,notifyAll()
join()
for waiting on other threadssleep()
for delaying execution
Locking and Synchronization
synchronized
blocks and methodsReentrantLock
ReadWriteLock
StampedLock
java.util.concurrent Tools
ExecutorService
,ThreadPoolExecutor
Future
,CompletableFuture
ForkJoinPool
,RecursiveTask
BlockingQueue
,ConcurrentHashMap
Real-World Scenarios
- Producer-Consumer using BlockingQueue
- Thread pools for task management
- Parallel file processing
Java Version Tracker
📌 What's New in Java Versions?
Java 8
- Lambdas for
Runnable
CompletableFuture
- Parallel streams
Java 9
Flow
API (Reactive Streams)
Java 11+
- Minor enhancements in
CompletableFuture
Java 21
- Structured concurrency
- Virtual threads (Project Loom)
- Scoped values
Best Practices and Common Pitfalls
✅ Best Practices
- Prefer
ExecutorService
over manual thread creation - Use immutable objects for shared data
- Use thread-safe collections from
java.util.concurrent
🚫 Common Pitfalls
- Race conditions
- Deadlocks
- False sharing
- Uncaught exceptions in threads
Multithreading Design Patterns
- Worker Thread
- Future Task
- Thread-per-message
- Producer-Consumer
Conclusion and Key Takeaways
- Multithreading improves performance and responsiveness
- Java provides robust APIs and concurrency tools
- Understand JMM, synchronization, and advanced constructs
- Prefer high-level constructs like thread pools or virtual threads
FAQs
Q1: Why shouldn't we call run()
directly?
A: It executes in the same thread instead of a new one. Use start()
to spawn a new thread.
Q2: What is the difference between volatile
and synchronized
?
A: volatile
ensures visibility; synchronized
ensures both mutual exclusion and visibility.
Q3: Can synchronized
methods lead to deadlocks?
A: Yes, if threads acquire locks in different orders.
Q4: What is the thread-safe way to increment a counter?
A: Use AtomicInteger.incrementAndGet()
.
Q5: When should I use ReentrantLock
over synchronized
?
A: When you need try-locking, timed locking, or interruptible locking.
Q6: What is false sharing?
A: When multiple threads modify variables that reside on the same cache line, causing performance degradation.
Q7: How do thread pools help performance?
A: They reduce the overhead of thread creation and reuse existing threads.
Q8: What are virtual threads in Java 21?
A: Lightweight threads managed by the JVM, ideal for I/O-bound workloads.
Q9: What is structured concurrency?
A: A model in Java 21+ to manage thread lifecycles hierarchically for safer concurrency.
Q10: How do I debug race conditions?
A: Use thread dumps, logging, and tools like jconsole
or VisualVM
to trace thread behavior.