了解下JUC的线程池学习三
1.线程池的状态常量,这里只详细分析其中一个,其他类同,这里看RUNNING
状态:
// -1的补码为:111-11111111111111111111111111111
// 左移29位后:111-00000000000000000000000000000
// 10进制值为:-536870912
// 高3位111的值就是表示线程池正在处于运行状态
private static final int RUNNING = -1 << COUNT_BITS;
2.控制变量ctl
的组成就是通过线程池运行状态rs
和工作线程数wc
通过或运算得到的:
// rs=RUNNING值为:111-00000000000000000000000000000
// wc的值为0:000-00000000000000000000000000000
// rs | wc的结果为:111-00000000000000000000000000000
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static int ctlOf(int rs, int wc) {
return rs | wc;
}
那么我们怎么从ctl
中取出高3位?上面源码中提供的runStateOf()
方法就是提取运行状态:
// 先把COUNT_MASK取反(~COUNT_MASK),得到:111-00000000000000000000000000000
// ctl位图特点是:xxx-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
// 两者做一次与运算即可得到高3位xxx
private static int runStateOf(int c){
return c & ~COUNT_MASK;
}
同理,取出低29位只需要把ctl
和COUNT_MASK
(000-11111111111111111111111111111
)做一次与运算即可。
注:这里有一个比较特殊的技巧,由于运行状态值存放在高3位,
所以可以直接通过十进制值(甚至可以忽略低29位,直接用ctl
进行比较,或者使用ctl
和线程池状态常量进行比较)
来比较和判断线程池的状态:
RUNNING(-536870912) < SHUTDOWN(0) < STOP(536870912) < TIDYING(1073741824) < TERMINATED(1610612736)
下面这三个方法就是使用这种技巧:
// ctl和状态常量比较,判断是否小于
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
// ctl和状态常量比较,判断是否小于或等于
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
// ctl和状态常量SHUTDOWN比较,判断是否处于RUNNING状态
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
最后是线程池状态的跃迁图:
PS:线程池源码中有很多中间变量用了简单的单字母表示,例如c就是表示ctl、wc就是表示worker count、rs就是表示running status。
学习来源:https://www.cnblogs.com/throwable/p/13574306.html