“This is the 15th day of my participation in the First Challenge 2022. For details: First Challenge 2022”
ThreadPoolExecutor Important parameters
ThreadPoolExecutor has several important member variables: keepAliveTime, allowCoreThreadTimeOut, poolSize, corePoolSize, maximumPoolSize. The following are introduced respectively:
-
CorePoolSize: The base size of the thread pool. The basic size is explained below.
-
MaximumPoolSize: maximum number of threads allowed in the thread pool.
Note that there is also largestPoolSize, which records the maximum number of threads that have ever occurred. Because setMaximumPoolSize() can change the maximum number of threads.
-
PoolSize: specifies the number of current threads in the thread pool.
-
AllowCoreThreadTimeOut: Whether to allow the core thread to exit due to timeout.
If this value is false and poolSize<=corePoolSize, the thread pool guarantees that the core threads are alive and will not timeout out.
If true, the timeout exit is allowed regardless of poolSize.
If poolSize>corePoolSize, this parameter, whether true or false, allows timeout.
Relevant judgments are as follows:
(poolSize > corePoolSize || allowCoreThreadTimeOut) Copy the code
-
KeepAliveTime: If a thread stays idle for longer than this value, it will exit due to timeout. Whether to allow timeout exits depends on the logic above.
PoolSize, corePoolSize, maximumPoolSize
PoolSize, corePoolSize, maximumPoolSize
When a new task is submitted:
- if
poolSize<corePoolSize
A new thread is added to handle the new task. - if
poolSize=corePoolSize
New tasks are put into a blocking queue to wait. - If the capacity of the blocking queue reaches its upper limit, and
poolSize<maximumPoolSize
New threads are added to process tasks. - If the blocking queue is full and
poolSize=maximumPoolSize
, the thread pool has reached its limit and will reject new tasks according to saturation policy RejectedExecutionHandler.
CorePoolSize <=maximumPoolSize, poolSize<=maximumPoolSize; PoolSize is not comparable to corePoolSize. PoolSize can be larger than corePoolSize.
Four thread pools
Executors provides four thread pools:
- NewCachedThreadPool: Cache thread pool. If the length of the thread pool exceeds the processing requirement, idle threads can be reclaimed. If none are reclaimed, new threads can be created.
- NewFixedThreadPool: a fixed-length thread pool that controls the maximum number of concurrent threads, and the excess threads wait in the queue.
- NewScheduledThreadPool: Scheduled thread pool that supports scheduled and periodic task execution.
- NewSingleThreadExecutor: single-threaded thread pool that uses a unique thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).
CorePoolSize and maximumPoolSize are available in each thread pool.
Through several newXXX function source can be known, the source code is as follows:
newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Copy the code
The corePoolSize and maximumPoolSize of a fixed-length thread pool are the same. It’s all set points.
newCachedThreadPool
public static ExecutorService newCachedThreadPool(a) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Copy the code
CorePoolSize is 0, maximumPoolSize is int maximum.
newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor(a) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1.1.0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Copy the code
Single-threaded thread pools corePoolSize and maximumPoolSize are both 1.
newScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
Copy the code
The scheduled thread pool uses a subclass of ThreadPoolExecutor, and you can see that corePoolSize is defined and maximumPoolSize is int maximum.
Note that corePoolSize and maximumPoolSize are not final because setCorePoolSize and setMaximumPoolSize() can be changed.
Blocking queue
What is the saturation value of the blocking queue mentioned above?
You can see this in the code above
The default size of LinkedBlockingQueue is the maximum size of int, as shown below:
public LinkedBlockingQueue(a) {
this(Integer.MAX_VALUE);
}
Copy the code
(2) The scheduled thread pool uses the DelayedWordQueue, which defaults to 16, but can grow dynamically, and the maximum value is the maximum value of int, as follows:
private static final int INITIAL_CAPACITY = 16;
privateRunnableScheduledFuture<? >[] queue =newRunnableScheduledFuture<? >[INITIAL_CAPACITY];private void grow(a) {
int oldCapacity = queue.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
if (newCapacity < 0) // overflow
newCapacity = Integer.MAX_VALUE;
queue = Arrays.copyOf(queue, newCapacity);
}
Copy the code
SynchronousQueue is used for the cache thread pool, which has no saturation value, and corePoolSize is 0 by default. So it creates a new thread that has to do with the SynchronousQueue mechanism, which I won’t go into here, but if you’re interested you can explore this class.