The ThreadPoolExecutor is the core implementation behind Java's Executor framework. It manages a pool of worker threads and efficiently executes submitted tasks without creating a new thread for every request. Internally, it maintains thread counts, task queues, and thread lifecycle information to determine whether to reuse existing threads, create new ones, or terminate idle threads.
Key Points: • ThreadPoolExecutor tracks worker threads using an internal worker count and thread state management mechanism. • Active threads are those currently executing tasks, which can be monitored using methods such as getActiveCount(), while completed and terminated threads are managed automatically by the pool. • Idle threads may be terminated after the configured keepAliveTime if they exceed the core pool size, helping optimize resource utilization.
Internal Working of ThreadPoolExecutor:
1. Task Submission • A task is submitted using execute() or submit().
2. Core Thread Check • If the current thread count is less than corePoolSize, a new worker thread is created.
3. Queue Insertion • If all core threads are busy, the task is placed into the work queue.
4. Maximum Pool Check • If the queue is full and thread count is below maximumPoolSize, additional threads are created.
5. Rejection Policy • If both the queue and thread pool are full, the configured RejectedExecutionHandler is invoked.
6. Thread Cleanup • Idle threads beyond the core pool size are terminated after keepAliveTime expires.
Example: Consider an e-commerce application processing thousands of orders. Instead of creating a new thread for every order, a ThreadPoolExecutor reuses existing worker threads, improving performance and reducing thread-creation overhead.
Code Example:
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class ExecutorDemo {
public static void main(String[] args) {
ThreadPoolExecutor executor =(ThreadPoolExecutor) Executors.newFixedThreadPool(5);
executor.execute(() ->
System.out.println(
"Task Executed"));
System.out.println(
"Active Threads : "
+ executor.getActiveCount());
System.out.println(
"Pool Size : "
+ executor.getPoolSize());
executor.shutdown();
}
}Interview Tip: A concise interview answer is: ThreadPoolExecutor maintains worker threads, a task queue, and thread state information internally. When a task is submitted, it first uses available core threads, then queues tasks, and finally creates additional threads up to maximumPoolSize if required. Active threads are tracked internally, idle threads can be terminated after keepAliveTime, and thread reuse improves performance by avoiding frequent thread creation.