Concurrency in Java enables multiple threads to run in parallel, allowing applications to utilize CPU cores efficiently and improve throughput. This guide explores Java concurrency — from the basic Executor
interface to advanced constructs like ThreadPoolExecutor
, ScheduledExecutorService
, and concurrency utilities like CountDownLatch
, CyclicBarrier
, and more.
1. Executor vs. ExecutorService
✅ Executor
The simplest interface for task execution:
Executes the command asynchronously using an implementation-defined strategy.
✅ ExecutorService
More advanced than Executor
, it supports:
-
Lifecycle management
-
Task submission with results (Future)
-
Shutdown and termination
2. ⚙️ ThreadPoolExecutor: Fine-Grained Control
Why use ThreadPoolExecutor
?
Gives you full control over:
-
Thread counts
-
Queuing behavior
-
Rejection policies
Constructor:
Parameters:
Parameter | Description |
---|---|
corePoolSize | Minimum number of threads kept alive |
maximumPoolSize | Maximum threads allowed |
keepAliveTime | Idle time for non-core threads |
workQueue | Queues tasks before they are executed |
-
If current threads <
corePoolSize
, a new thread is created. -
If the core pool is full, the task is added to the queue.
-
If the queue is full and current threads <
maximumPoolSize
, a new thread is added. -
If all full → task is rejected.
3. 🧱 BlockingQueue in ThreadPoolExecutor
The BlockingQueue
is essential to handle task queuing:
-
Avoids thread explosion
-
Provides backpressure
-
Ensures predictable behavior under load
Common Implementations:
-
LinkedBlockingQueue
(unbounded) -
ArrayBlockingQueue
(bounded) -
SynchronousQueue
(direct hand-off, no queueing)
4. 🕰️ ScheduledThreadPoolExecutor
For running recurring or delayed tasks:
5. 🧰 Common Factory Methods in Executors
Class
The Executors
utility class provides easy-to-use factory methods to create various types of thread pools.
✅ Executors.newSingleThreadExecutor()
Runs tasks sequentially using a single thread.
✅ Executors.newFixedThreadPool(int n)
Reuses a fixed number of threads.
✅ Executors.newCachedThreadPool()
Creates new threads as needed and reuses idle ones.
✅ Executors.newScheduledThreadPool(int n)
Used for scheduling periodic/delayed tasks.
✅ Executors.newSingleThreadScheduledExecutor()
A single-thread version of the scheduled pool.
✅ Executors.newWorkStealingPool(int parallelism)
Uses the ForkJoinPool with multiple worker threads.
Method | Thread Behavior | Use Case |
---|---|---|
newSingleThreadExecutor() | 1 thread | Sequential task flow |
newFixedThreadPool(n) | Fixed-size threads | Stable load |
newCachedThreadPool() | Unlimited threads | Lightweight tasks |
newScheduledThreadPool(n) | Scheduled thread pool | Periodic tasks |
newSingleThreadScheduledExecutor() | 1 scheduled thread | Serial periodic jobs |
newWorkStealingPool() | ForkJoin threads | CPU-bound parallelism |
6. Runnable vs. Callable
Feature | Runnable | Callable<V> |
---|---|---|
Returns value? | ❌ | ✅ |
Checked exceptions? | ❌ | ✅ |
Submit method | execute() , submit() | submit() |
7. Producer-Consumer with BlockingQueue
Handles concurrency safely using queue-based coordination.
8. SynchronizedMap vs. ConcurrentHashMap
Feature | SynchronizedMap | ConcurrentHashMap |
---|---|---|
Lock granularity | Whole map | Bucket-level |
Iteration safety | No (ConcurrentModificationException ) | Yes |
9. CountDownLatch
10. CyclicBarrier
11. CountDownLatch vs. CyclicBarrier
Feature | CountDownLatch | CyclicBarrier |
---|---|---|
Reusability | ❌ One-time use | ✅ Can reset |
Waiting | One thread waits | All threads wait |
12. Deadlock
When threads wait on each other’s locks, creating a cycle.
Solution:
-
Lock ordering
-
Use
tryLock()
-
Reduce lock scope
13. Race Condition
Occurs when threads access shared state unsafely.
Solution:
-
Use
synchronized
-
Use atomic classes (e.g.,
AtomicInteger
)
14. Semaphore
Controls concurrent access to a resource:
15. ForkJoin Framework
Designed for recursive task decomposition:
✅ Summary
Mastering Java’s concurrency tools improves scalability and system utilization. Choose the right ExecutorService
based on your workload and use concurrency utilities to coordinate thread behavior.
🔗 Further Resources:
Comments
Post a Comment