上一段自己打了注释的源码吧 jdk版本是11和8的略有不同
线程池的一些属性和方法
// 记录线程池的状态信息 高三位是状态信息,其余位表示工作的worker数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 表示worker数量的位数也就是上面说的 其余位
private static final int COUNT_BITS = Integer.SIZE - 3;
// 求worker数量的掩码 1 左移 COUNT_BITS - 1
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
/*
* 计算woker的数量
* 按照现行的jdk(Integer.SIZE是32) COUNT_MASK就是 0001 1111 1111 1111 1111 1111 1111 1111
* ctl 与上这个就可以求出woker的数量
*/
private static int workerCountOf(int c) { return c & COUNT_MASK; }
execute方法 代码不多但是说到很多
public void execute(Runnable command) {
// 要提交的任务不能是null
if (command == null)
throw new NullPointerException();
// 获取ctl的值
int c = ctl.get();
// 如果当前woker的数量小于 核心线程数 则该判断为true
if (workerCountOf(c) < corePoolSize) {
/*
* 使用核心线程数的限制去开worker来执行这个任务
* 注意没有核心线程和非核心线程这一说 worker是没有区别的
* addWorker会失败 这里只需要了解 可能是因为线程池状态或者worker的数量引起addWorker失败
* 因为可能不只是一个线程在操作线程池可能其他线程也在操作
*/
if (addWorker(command, true))
return;
// 如果addWorker失败则ctl要重新获取因为不管是状态变还是worker数量变ctl都已经变了你需要重新获取最新值
c = ctl.get();
}
/*
* 在当前worker数量大于等于corePoolSize或者上面的addWorker失败之后才会走到这里
* 经过上面分析可能有两种可能 1、线程的状态发生改变 2、当前worker数量不小于核心线程数
* 第一个判断是查看一下当前线程的状态是否是running状态
* 在满足第一条件下会尝试往工作队列里面添加这个任务 但是有可能失败 工作队列可能满了
*/
if (isRunning(c) && workQueue.offer(command)) {
// 走到这里说明offer之前是running状态 放入工作队列成功了 需要重新获取当前状态 因为有可能放进去之后线程状态变了
int recheck = ctl.get();
/*
* 如果offer之后线程池不是running了 需要尝试remove刚才的任务
* 不是running的状态下 remove也有可能失败,他可能被执行了
*/
if (! isRunning(recheck) && remove(command))
// 如果remove成功了需要拒绝这个任务
reject(command);
/*
* 因为走到这里一定是 offer成功了
* 这个判断是为了防止没有worker 但是队列里面有任务 没人执行
* 这个是有可能的 工作一段时间后worker的数量为0 和 allowCoreThreadTimeOut()这个方法有关系
*
* 上一个if判断的!isRuning 是true remove失败的时候 有可能 workerCountOf(recheck) == 0 为true
* 这个时候线程池肯定是不让你再添加线程的
*/
else if (workerCountOf(recheck) == 0)
/*
* 如果出现 线程池是running worker是0 队列有任务 需要添加一个worker执行这些任务
* 如果出现 线程池不是running 但是remove失败 worker是0 线程池是不允许添加worker的这个逻辑在addworker方法里面
*
*/
addWorker(null, false);
}
/*
* 如果用核心线程数限制开worker执行任务失败
* 或者 线程池状态不是running
* 或者 工作队列已经满了
* 使用最大线程数限制开worker执行任务
*/
else if (!addWorker(command, false))
// 失败的原因有 1、worker达到非核心线程数 2、线程池的状态变了不是running了 则拒绝这个任务
reject(command);
}