了解下JUC的线程池学习八(processWorkerExit方法源码分析)
1.介绍
processWorkerExit()方法是为将要终结的Worker做一次清理和数据记录工作
(因为processWorkerExit()方法也包裹在runWorker()方法finally代码块中,
其实工作线程在执行完processWorkerExit()方法才算真正的终结)。
2.源码
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// 因为抛出用户异常导致线程终结,直接使工作线程数减1即可
// 如果没有任何异常抛出的情况下是通过getTask()返回null引导线程
//正常跳出runWorker()方法的while死循环从而正常终结,这种情况下,在getTask()中已经把线程数减1
if (completedAbruptly)// If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 全局的已完成任务记录数加上此将要终结的Worker中的已完成任务数
completedTaskCount += w.completedTasks;
// 工作线程集合中移除此将要终结的Worker
workers.remove(w);
} finally {
mainLock.unlock();
}
// 见下一小节分析,用于根据当前线程池的状态判断是否需要进行线程池terminate处理
tryTerminate();
int c = ctl.get();
// 如果线程池的状态小于STOP,也就是处于RUNNING或者SHUTDOWN状态的前提下:
// 1.如果线程不是由于抛出用户异常终结,如果允许核心线程超时,则保持线程池中至少存在一个工作线程
// 2.如果线程由于抛出用户异常终结,或者当前工作线程数,那么直接添加一个新的非核心线程
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
// 如果允许核心线程超时,最小值为0,否则为corePoolSize
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
// 如果最小值为0,同时任务队列不空,则更新最小值为1
if (min == 0 && ! workQueue.isEmpty())
min = 1;
// 工作线程数大于等于最小值,直接返回不新增非核心线程
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
总结:代码的后面部分区域,会判断线程池的状态,
如果线程池是RUNNING或者SHUTDOWN状态的前提下,
如果当前的工作线程由于抛出用户异常被终结,那么会新创建一个非核心线程。
如果当前的工作线程并不是抛出用户异常被终结(正常情况下的终结),那么会这样处理:
第一种:allowCoreThreadTimeOut为true,也就是允许核心线程超时的前提下,
如果任务队列空,则会通过创建一个非核心线程保持线程池中至少有一个工作线程。
第二种:allowCoreThreadTimeOut为false,如果工作线程总数大于corePoolSize则直接返回,
否则创建一个非核心线程,也就是会趋向于保持线程池中的工作线程数量趋向于corePoolSize。
processWorkerExit()执行完毕之后,意味着该工作线程的生命周期已经完结。
学习来源:https://www.cnblogs.com/throwable/p/13574306.html

浙公网安备 33010602011771号