Java线程池---addWorker⽅法简单解析
ctl属性:其前三位是运⾏状态位,后29位是线程个数
注:增加work时有重⼊锁
主要步骤
1. 获取当前线程池的状态,如果是STOP,TIDYING,TERMINATED状态的话,则会返回false,如果现在状态是SHUTDOWN,只有在
要运⾏的任务为空且还有还有⼯作任务时才可以添加线程,其他shutdown时不允许创建线程(线程池的状态不符合直接返回)
2. 通过⾃旋的⽅式,判断要添加的Worker是否是corePool,如果是的话,那么则判断当前的workerCount是否⼤于corePoolsize,否
则则判断是否⼤于maximumPoolSize,如果满⾜的话,说明workerCount超出了线程池⼤⼩,直接返回false。如果⼩于的话,那么判断是否成功将WorkerCount通过CAS操作增加1,如果增加成功的话。则进⾏到第3步,否则则判断当前线程池的状态,如果现在获取到的状态与进⼊⾃旋的状态不⼀致的话,那么
则通过continue retry重新进⾏状态的判断。(判断是线程个数不⼤于最⼤值,不⼤于最⼤线程数的话⾃旋通过cas增加线程数,cas成功进⼊3步,cas失败的话判断线程池状态发⽣改变1开始重新判断线程池状态,只是线程数发⽣变化的话内部循环⾃旋即可)
3. 如果满⾜了的话,那么则创建⼀个新的Worker对象,然后获取线程池的重⼊锁后,判断当前线程池的状态,如果当前线程池状态为
STOP,TIDYING,TERMINATED的话,那么调⽤decrementWorkerCount将workerCount减⼀,然后调⽤tryTerminate停⽌线程池,并且返回false。(获取锁判断线程池的状态是运⾏中或者finlize中,是的话添加。添加成功后启动,失败后处理下失败)
注:ctl打包了运⾏状态runState和已被允许启动但不允许停⽌的⼯⼈数workerCount,⾼三位表⽰运⾏状态。双层for循环是因为最内层是需要cas,内层在cas失败,但是线程的运⾏状态没有改变只是work数量改变时继续cas即可,即最内层的循环。如果线程池的运⾏状态改变了,则需要重新读取线程池的运⾏状态。⽽外层是需要重新读取运⾏状态的。
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = (); // Re-rea
d ctl
if (runStateOf(c) != rs)
continue retry;
java线程池创建的四种// 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) {
if (t != null) {
final ReentrantLock mainLock = this.mainLock; mainLock.lock();
try {
/
/ Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = ());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && 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;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论