了解下JUC的线程池学习九(tryTerminate方法源码分析)
1.介绍
每个工作线程终结的时候都会调用tryTerminate()方法
2.源码
final void tryTerminate() {
for (;;) {
int c = ctl.get();
// 判断线程池的状态,如果是下面三种情况下的任意一种则直接返回:
// 1.线程池处于RUNNING状态
// 2.线程池至少为TIDYING状态,也就是TIDYING或者TERMINATED状态,意味着已经走到了下面的步骤,线程池即将终结
// 3.线程池至少为STOP状态并且任务队列不为空
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
return;
// 工作线程数不为0,则中断工作线程集合中的第一个空闲的工作线程
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// CAS设置线程池状态为TIDYING,如果设置成功则执行钩子方法terminated()
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
// 最后更新线程池状态为TERMINATED
ctl.set(ctlOf(TERMINATED, 0));
// 唤醒阻塞在termination条件的所有线程,这个变量的await()方法在awaitTermination()中调用
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
// 中断空闲的工作线程,onlyOne为true的时候,只会中断工作线程集合中的某一个线程
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
// 这里判断线程不是中断状态并且尝试获取锁成功的时候才进行线程中断
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
// 这里跳出循环,也就是只中断集合中第一个工作线程
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
3.问题
tryTerminate()方法的第二个if代码逻辑:工作线程数不为0,则中断工作线程集合中的第一个空闲的工作线程。
方法API注释中有这样一段话:
If otherwise eligible to terminate but workerCount is nonzero,
interrupts an idle worker to ensure that shutdown signals propagate.
当满足终结线程池的条件但是工作线程数不为0,
这个时候需要中断一个空闲的工作线程去确保线程池关闭的信号得以传播。
学习来源:https://www.cnblogs.com/throwable/p/13574306.html

浙公网安备 33010602011771号