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) {
推荐阅读
- rar解压工具哪个好 免费rar解压软件哪个好
- 忘记手机指纹解锁数字密码怎么处理掉
- 该怎样才能发表微博,为什么发的微博无法显示
- 电视机网络版和电视版有什么区别
- hwlal00是什么手机,华为hwl一al00是什么型号
- 影视大全该怎样才可以离线缓存
- 怎么给标注尺寸,ps怎么给中的物品标注尺寸大小
- 进口车查询是哪个网站,进口车从玻璃上怎么看是哪年款
- 黑云翻墨未遮山的下一句,黑云翻墨未遮山描绘的画面是什么?
