回答
默认情况下,线程池的核心线程是不会被回收的,即使它们处于空闲状态。但是 ThreadPoolExecutor
还是提供了一个参数来控制这个行为,通过 allowCoreThreadTimeOut(true)
设置后,核心线程在空闲超过keepAliveTime
时就会被回收。
我们直接看源码,直接看 ThreadPoolExecutor
中 runWorker()
:
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
// 不断从任务队列中拿任务执行,直到获取为空
}
completedAbruptly = false;
} finally {
// 当没有任务后,执行
processWorkerExit(w, completedAbruptly);
}
}
当任务队列中没有任务执行了就会执行 processWorkerExit()
,该方法主要用于清理一些工作线程:
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// ...
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
// 如果 allowCoreThreadTimeOut = true,则 min 为 0
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
// min == 0 但是工作线程为空位,则至少需要创建一个线程,否则就是 0
if (min == 0 && ! workQueue.isEmpty())
min = 1;
// 线程池中的线程数 >= min 就直接退出
if (workerCountOf(c) >= min)
// 这里直接返回
return; // replacement not needed
}
addWorker(null, false);
}
}
从 processWorkerExit()
中可以看出,如果 allowCoreThreadTimeOut
设置为 true
,则大概率情况下是不会调用 addWorker(null, false)
去创建线程的,它会直接返回,线程自然消亡。