大家好,我是大明哥,一个专注「死磕 Java」系列创作的硬核程序员。
本文已收录到我的技术网站:www.skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经
回答
默认情况下,线程池的核心线程是不会被回收的,即使它们处于空闲状态。但是 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) 去创建线程的,它会直接返回,线程自然消亡。
关于线程池的原理,请阅读:什么是线程池?它的核心原理是什么?