for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
这是一个赋状态值的方法
先进入一个无限for循环
建立临时变量c 赋值为ctl的get方法返回值 这个c代表的是 当前的状态
进入if判断 判断runStateAtLeat方法或ctl的cas方法返回true 就跳出循环
其中runStateAtLeast就是判断当前状态的数值大于等于目标状态
ctl的cas方法是将当前状态设为 目标状态和worker数按位或的结果 也就是说cas方法赋的状态前四位是状态码 后28位是线程数
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
这个是试图关闭线程池的方法
首先进入无限循环
获取线程池的状态
判断如果是RUNNING状态 或 TIDYING状态以上 或SHUTDOWN状态但工作队列不为空 就结束方法
判断如果worker数量不为0 调用 interruptIdleWorkers方法 并传入常量ONLY_ONE=true 打断其中一个持有worker的线程 然后方法返回
调用mainLock锁住当前代码块 在try块里 判断如果状态设为TIDYING 并且状态位的线程数为0 成功后 调用terminated()方法 terminated方法也包裹在一个try块了 terminated的finally块里 将状态设为TERMINATED 线程数设为0 termination的Condition调用signalAll方法唤醒所有termination等待队列的线程 实际就是执行终止工作的线程都唤醒
最后mainLick解锁
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}
这个方法是检查关闭线程池前 每隔worker锁绑定的线程是否可以使用
首先获取SecurityManager
判断一旦系统的SecurityManager不为空 调用checkPermission方法 传入shutdownPerm 检查可否有关闭线程的权限
将mainLock上锁
遍历每个worker 用SecurityManager检查每个worker的线程是否可以使用
最后mainLock解锁