if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get;
}
//如果不小于corePoolSize , 则将任务添加到workQueue队列 。
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get;
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(, false);
}
//如果放入workQueue失败,则创建线程执行任务,如果这时创建线程失败(当前线程数不小于maximumPoolSize时),就会调用reject(内部调用handler)拒绝接受任务 。
else if (!addWorker(command, false))
reject(command);
}
AddWorker方法:
- 创建Worker对象,同时也会实例化一个Thread对象 。在创建Worker时会调用threadFactory来创建一个线程 。
- 然后启动这个线程 。
看源码第一反应就是这个CTL到底是个什么东东?有啥用?一番研究得出如下结论:
CTL属性包含两个概念:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static int ctlOf(int rs, int wc) { return rs | wc; }
- runState:即rs 表明当前线程池的状态,是否处于Running,Shutdown , Stop,Tidying 。
- workerCount:即wc表明当前有效的线程数 。
private static final int COUNT_BITS = Integer.SIZE - 3;
既然是29位那么就是Running的值为:
1110 0000 0000 0000 0000 0000 0000 0000
|||
31~29位
那低28位呢,就是记录当前线程的总线数啦:
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
从上述代码可以看到workerCountOf这个函数传入ctl之后,是通过CTL&CAPACITY操作来获取当前运行线程总数的 。
也就是RunningState|WorkCount&CAPACITY,算出来的就是低28位的值 。因为CAPACITY得到的就是高3位(29-31位)位0,低28位(0-28位)都是1,所以得到的就是ctl中低28位的值 。
而runStateOf这个方法的话,算的就是RunningState|WorkCount&CAPACITY , 高3位的值,因为CAPACITY是CAPACITY的取反,所以得到的就是高3位(29-31位)为1,低28位(0-28位)为0,所以通过&运算后,所得到的值就是高3为的值 。
简单来说就是ctl中是高3位作为状态值,低28位作为线程总数值来进行存储 。
2.3.2 shutdownNow和shutdown的区别
看源码发现有两种近乎一样的方法,shutdownNow和shutdown,设计者这么设计自然是有它的道理,那么这两个方法的区别在哪呢?
- shutdown会把线程池的状态改为SHUTDOWN,而shutdownNow把当前线程池状态改为STOP 。
- shutdown只会中断所有空闲的线程,而shutdownNow会中断所有的线程 。
- shutdown返回方法为空,会将当前任务队列中的所有任务执行完毕;而shutdownNow把任务队列中的所有任务都取出来返回 。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread;
Runnable task = w.firstTask;
w.firstTask = ;
w.unlock; // allow interrupts
boolean completedAbruptly = true;
try {
while (task != || (task = getTask) != ) {
w.lock;
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get, STOP) ||
(Thread.interrupted &&
runStateAtLeast(ctl.get, STOP))) &&
!wt.isInterrupted)
wt.interrupt;
try {
beforeExecute(wt, task);
Throwable thrown = ;
try {
task.run;
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = ;
w.completedTasks++;
w.unlock;
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
就是任务在并不只执行创建时指定的firstTask第一任务 , 还会从任务队列的中自己主动取任务执行,而且是有或者无时间限定的阻塞等待 , 以保证线程的存活 。
默认的是不允许 。
2.4 CountDownLatch和CyclicBarrier区别
countDownLatch是一个计数器,线程完成一个记录一个 , 计数器递减,只能只用一次 。
推荐阅读
- iphone14技术规格
- 进程和线程:你了解它们的区别吗英语
- 阳光玫瑰葡萄大棚怎么建,阳光玫瑰葡萄种植技术与管理
- 荷兰豆种植 荷兰豆种植技术与管理
- 手机格式化照片用技术手段还会被恢复吗
- 蜜蜂怎么养殖 蜜蜂怎么养殖技术视频
- 物联网应用技术属于什么专业类别
- 现代式短跑技术强调的是什么跑法
- 蛋鸡养殖技术 蛋鸡养殖技术培训
- 物联网应用技术是什么
