Java Thread Pool Notes
A guide to thread pool core parameters and two creation methods, helping you correctly choose, configure, and tune
ThreadPoolExecutorin your projects.
1. Introduction to Thread Pools
As the name suggests, a thread pool is a resource pool that manages a series of threads. It provides a way to limit and manage thread resources. Each thread pool also maintains some basic statistics, such as the number of completed tasks.
Benefits of using thread pools:
- Reduce resource consumption. Reusing already created threads reduces the overhead of thread creation and destruction.
- Improve response speed. When a task arrives, it can be executed immediately without waiting for thread creation.
- Improve thread manageability. Threads are scarce resources. Unlimited creation not only consumes system resources but also reduces system stability. Thread pools enable unified allocation, tuning, and monitoring.
2. Introduction to ThreadPoolExecutor Class
The ThreadPoolExecutor class provides four constructors. Let’s look at the longest one, as the other three are based on it.
/**
* Creates a new ThreadPoolExecutor with the given initial parameters.
*/
public ThreadPoolExecutor(int corePoolSize, // Core thread count in the pool
int maximumPoolSize, // Maximum thread count in the pool
long keepAliveTime, // Maximum time idle threads survive when count exceeds core
TimeUnit unit, // Time unit
BlockingQueue<Runnable> workQueue, // Task queue for storing pending tasks
ThreadFactory threadFactory, // Thread factory for creating threads, usually default
RejectedExecutionHandler handler // Rejection policy for handling tasks when overloaded
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
The 3 most important parameters of ThreadPoolExecutor:
corePoolSize: The maximum number of threads that can run simultaneously when the task queue hasn’t reached capacity.maximumPoolSize: When the task queue is full, the number of threads that can run simultaneously becomes the maximum thread count.workQueue: When a new task arrives, it first checks if the current running thread count has reached the core thread count. If so, the new task is placed in the queue.
Other common parameters of ThreadPoolExecutor:
keepAliveTime: When the thread pool’s thread count is greater thancorePoolSize, if no new tasks are submitted, non-core threads won’t be destroyed immediately but will wait until the waiting time exceedskeepAliveTimebefore being recycled.unit: Time unit for thekeepAliveTimeparameter.threadFactory: Used by the executor when creating new threads.handler: Rejection policy.
The following diagram can deepen your understanding of the relationship between thread pool parameters (image source: “Java Performance Tuning in Action”):

3. Two Ways to Create Thread Pools
Method 1: Through the ThreadPoolExecutor constructor (recommended).

Implementation through the constructor method.
Method 2: Through the Executors utility class in the Executor framework.
The thread pool creation methods provided by the Executors utility class are shown below:

The “Alibaba Java Development Manual” mandates that thread pools should not be created using Executors, but rather through the ThreadPoolExecutor constructor. This approach makes developers more aware of the thread pool’s operating rules and avoids the risk of resource exhaustion.