(jdk12)addWorker源代码分析:
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))
return false;
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)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
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;。



