ExecutorService & ThreadPoolExecutor Tuning
1Concept
`ExecutorService` decouples task submission from execution thread pools. `ThreadPoolExecutor` parameters: 1. `corePoolSize` (baseline threads); 2. `maximumPoolSize` (burst cap); 3. `workQueue` (bounded `ArrayBlockingQueue` prevents OOM); 4. `RejectedExecutionHandler` (CallerRunsPolicy, AbortPolicy).
2Architecture Diagram
Task Submitted ---> [ corePoolSize full? ] --No--> Spawn new thread
|
Yes
v
[ workQueue full? ] --No--> Enqueue task
|
Yes
v
[ maximumPoolSize reached? ] --No--> Spawn burst thread
|
Yes
v
[ Trigger RejectedExecutionHandler ]3Code Example
Core Java
import java.util.concurrent.*;
public class ExecutorTuningDemo {
public static void main(String[] args) throws Exception {
// Production-grade ThreadPoolExecutor configuration
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // corePoolSize
4, // maximumPoolSize
60L, TimeUnit.SECONDS, // keepAliveTime
new ArrayBlockingQueue<>(10),// Bounded Queue (prevents OOM)
new ThreadPoolExecutor.CallerRunsPolicy() // Backpressure handler
);
for (int i = 1; i <= 4; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " running on " + Thread.currentThread().getName());
});
}
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
}4Expected Output
Task 1 running on pool-1-thread-1 Task 2 running on pool-1-thread-2 Task 3 running on pool-1-thread-1 Task 4 running on pool-1-thread-2
5Key Takeaways
- ✓NEVER use `Executors.newCachedThreadPool()` or `newFixedThreadPool()` without bounds in production; unbounded queues cause OutOfMemoryError.
- ✓`CallerRunsPolicy` provides graceful backpressure by throttling task submitters.
- ✓Always call `executor.shutdown()` and `awaitTermination()` during application graceful shutdown.