(jdk12)addWorker源代码分析:
/*
常量说明:
int corePoolSize:核心线程数量,默认情况下,即时没有任务,线程池也会维持核心线程不被销毁;
int maximumPoolSize:最大线程数量,当没有空闲线程可用时,线程池会创建新线程来执行任务,线程总数不会超过此属性;
long keepAliveTime:线程空闲时间,超过该时间后,线程池会销毁线程,默认情况下,核心线程不会被销毁;
TimeUnit unit:线程空闲时间的时间单位;
BlockingQueue workQueue:任务缓存队列,当线程数已达最大数量,且没有空闲线程时,新任务会入队等待;
ThreadFactory threadFactory:创建线程使用的线程工厂,其中可以设置线程名称,方便在日志中排查问题;
RejectedExecutionHandler handler:拒绝策略,当任务缓存队列满后,新收到的任务会交由拒绝策略处理。
最后三个属性应当按照实际业务需求进行实例化,而非使用Executors提供的默认实现。
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (int c = ctl.get();😉 {
// Check if queue empty only if necessary.
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP)
//⬆️判断当前的线程池处于STOP状态或TIDYING状态或TERMINATED状态
|| firstTask != null
//当前线程池没有任务
|| workQueue.isEmpty()))
//当前阻塞队列中没有待执行任务
return false;
for (;;) {
if (workerCountOf(c)
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
/*
对于boolean类型core的说明: if true use corePoolSize as bound, else maximumPoolSize. 和COUNT_MASK相与操作表示取低29位,即取core选取的值的后29位表示容量
*/
return false;
/*
⬆️如果线程数量超过了最大容量,这时候addWorker方法返回的值是false。注意⚠️corePoolSize和maximumPoolSize只需要选取其中的值进行容量判断即可。
/
if (compareAndIncrementWorkerCount©)
break retry;
/
通过查询API得知:compareAndIncrementWorkerCount(c)方法用于比较线程池的ctl和当前线程池的WorkerCount(低29位+1)之后大小的,如果超过表示当前线程池已经满了,没有办法添加线程,跳出retry
*/
c = ctl.get(); // Re-read ctl
if (runStateAtLeast(c, SHUTDOWN))
//如果clt的高三位没有变成RUNNING,即c>=SHUTDOWN那么返回true,表示线程池状态变更失败,retry
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
//线程池状态clt修改完毕,开始添加线程
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
//⬆️设置线程添加判断位(workerAdded)和 线程运行位(workerStarted)创建新线程Worker w = null
try {
w = new Worker(firstTask);
//⬆️将传入的runnable类作为新建线程的firstTask
final Thread t = w.thread;
//⬆️将w的Runnable类的线程传给t
//thread方法说明:Thread this worker is running in. Null if factory fails.
if (t != null) {
//⬆️判断w线程所使用的Runnable能否成功运行,如果不行返回null
//确认新建线程t和Worker类w创建初始化成功之后,开始创建锁
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
//⬆️创建并持有锁
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
//⬆️try的目的是在持有锁的期间再次确认,当线程t的Runnable类是否出错,在持有锁的期间这个线程池是否被关闭,如果出现其中一种情况,退出添加线程池的方法
int c = ctl.get();
if (isRunning(c) ||
(runStateLessThan(c, STOP) && firstTask == null)) {
/*确定线程池状态为:要么是RUNNING,要么是SHUTDOWN状态(即不再创建新线程,但会把阻塞队列中的任务执行完)且fistTask为空(firstTask是用户传入的Runnable任务)如果为空,那么无需创建新线程进行执行,也满足线程池SHUTDOWN状态的定义。
*/
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
/*确认完线程池正处于可添加线程的状态之后,确保要添加的新线程已经开始,但还没死亡
API解释isAlive的注释:
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
*/
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
//⬆️在线程池中添加的Worker类,即新建线程,修改相关参数:线程池的容量参数largestPoolSize,注意这个largestPoolSize只能在持有锁mainLock的状态下访问
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
//⬆️放弃锁mainLock的持有权,判断线程池中添加新线程的操作是否成功,如果成功,线程开始运行,线程池也开始运行,如果失败调用,调用addWorkerFailed方法,即删除Worker类的w,修改WorkerCount(线程池房钱线程数量wc)并尝试关闭线程池的方法,返回线程是否开始运行的判断值workerStarted;。