private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//&&实质上是在缩小范围
if (rs >= SHUTDOWN &&
//当线程池的状态是shutdown,队列中还有任务时,可以添加worker,但跟随这个worker进来的任务必须为空
!(rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()))
return false;
/**
* 上面没有阻断 意味着两种情况
* 1、线程池的状态是running
* 2、线程池的状态是shutdown,但是队列中还有需要执行的任务,而且跟随这次的worker进来的任务为空(这实质上保证了在shutdown状态下,我们可以执行完队列中的任务)
*/
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY |
/**
* core是true,用核心线程数检查
* core是false,用最大线程数检查
**/
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//假如这个原子操作成功,说明有人修改了c的值,这时我们再用c去计算,就会得到错误的结果
if (compareAndIncrementWorkerCount(c))//增加worker的数量就是在这里
break retry;
//有人修改了c,我们获取新的c
c = ctl.get(); // Re-read ctl
//看一下他们改的是状态还是worker数量
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
//什么情况会拿不到线程呢?
if (t != null) {
//为什么又要做一个引用指向mainLock?
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
//workers的结构为什么要用hashset?
workers.add(w);//同一时刻只能有一个线程向workers中添加worker
int s = workers.size();
//这个largestPoolSize有啥用?比它大了,就更新
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
网友评论