keepAliveTime含义
ThreadPoolExecutor
的 javadoc 对 keepAliveTime
参数的解释:
keepAliveTime when the number of threads is greater than the core,
this is the maximum time that excess idle threads will wait for new
tasks before terminating.
大致意思是:keepAliveTime
就是 当线程数大于核心线程数时,在终止前,多余的空闲线程等待新任务的最长时间。
大白话说明
假设,核心线程数10,最大线程数30,keepAliveTime是 3秒
随着任务数量不断上升,线程池会不断的创建线程,直到到达核心线程数10,就不创建线程了,这时多余的任务通过加入阻塞队列来运行,当超出(阻塞队列长度+核心线程数)时,
这时不得不扩大线程个数来满足当前任务的运行,这时就需要创建新的线程了(最大线程数起作用),上限是最大线程数30,
那么,超出核心线程数10并小于最大线程数30的可能新创建的这20个线程相当于是"借"的,如果这20个线程空闲时间超过keepAliveTime,就会被退出。
注:核心线程的关闭 由
ThreadPoolExecutor#allowCoreThreadTimeout
决定,默认 allowCoreThreadTimeout=false,代表不会 超时终止,就是不受 KeepLive的影响。
public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
// 全局变量,自动初始化,boolean 类型默认是 false
private volatile boolean allowCoreThreadTimeOut;
// 略
// 设置 核心线程是否可以 超时终止,默认 allowCoreThreadTimeOut=false
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();
}
}
// 略
}
但是我有两个疑问
-
线程为什么会空闲
没有任务时线程就会空闲下来,在线程池中任务是任务(Runnale)线程是线程(Worker)
-
线程为什么要退出
通常超出核心线程的线程是“借”的,也就是说超出核心线程的情况算是一种能够预见的异常情况,并且这种情况并不常常发生(如果常常发生,那我想你应该调整你的核心线程数了),所以这种不经常发生而创建的线程为了避免资源浪费就应该要退出
我们需要看一下java.util.concurrent.ThreadPoolExecutor#getTask
源码和javadoc 注释来验证上面一段话的含义:
ThreadPoolExecutor#getTask javadoc
/**
* Performs blocking or timed wait for a task, depending on
* current configuration settings, or returns null if this worker
* must exit because of any of:
* 1. There are more than maximumPoolSize workers (due to
* a call to setMaximumPoolSize).
* 2. The pool is stopped.
* 3. The pool is shutdown and the queue is empty.
* 4. This worker timed out waiting for a task, and timed-out
* workers are subject to termination (that is,
* {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
* both before and after the timed wait, and if the queue is
* non-empty, this worker is not the last thread in the pool.
*
* @return task, or null if the worker must exit, in which case
* workerCount is decremented
*/
大致意思:
执行任务阻塞或时间等待,具体取决于当前配置设置,如果此工作线程返回 null
就必须退出,可能是因为以下任何一个原因造成:
- 这里有超过最大线程池大小的工作线程(最大线程池大小 由 setMaximumPoolSize 设置)。
- 线程池已经停止了。
- 线程池已关闭,并且阻塞队列为空。
- 工作线程等待任务,已经超时了,那么超时的工作线程将会被终止。(代码描述:allowCoreThreadTimeOut || workerCount > corePoolSize)
ThreadPoolExecutor#getTask 源码
private Runnable getTask() {
boolean timedOut = false;<