JAVA定义了原子变量AtomicInteger,实质就是整型数。我们知道整数类型的长度为32位,这里就将整型数包装了两个内容
- runState:高的三位表示线程池的状态,
- workCount:低的29为表示线程池的工作线程数量。
源码
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
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; }
解析
- private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
实际就是通过ctlOf方法初始化了原子变量ctl,其结果为RUNING和0的或运算结果。就是RUNNING.
- private static final int RUNNING = -1 << COUNT_BITS;
在从l4看RUNNING的值,-1 << COUNT_BITS:就是-1左移COUNT_BITS位。Integer.SIZE 是32,所以COUNT_BITS就是29.
-1用32位的二进制表示为32个1。所以左移29位得:1110 0000 00000000 00000000 00000000
所以ctl的初始值就是它,-536870912 。最高位为表示符号。所以为负数。
- private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
同理,0,1,2,3左移29位后的值分别表示SHUTDOWN,STOP, TIDYING, TERMINATED.
他们的高三位分别是,000/001/010/011/ 00000 00000000 00000000 00000000.
所以,线程池状态之间的转换为:
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING
* When both queue and pool are empty
* STOP -> TIDYING
* When pool is empty
* TIDYING -> TERMINATED
* When the terminated() hook method has completed
*
* Threads waiting in awaitTermination() will return when the
* state reaches TERMINATED.
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
CAPACITY与线程池中的线程数量和状态的获取有关的常量。前面我们知道1<< COUNT_BITS:1左移32位,是0010 0000 00000000 00000000 00000000.
再-1,所以CAPACITY的值为:0001 1111 11111111 111111111 11111111.private static int runStateOf(int c) { return c & ~CAPACITY; }
那CAPACITY如何与状态相关联,又如何得到通过c返回当前状态的呢。
假如当前状态为RUNNING,可以通过ctl.get()方法获取c值,他的高三位表示状态,第三位表示当前线程数量。
~CAPACITY表示对CAPACITY取反,所以~CAPACITY的高三位为1,低29位为0。
再和c进行与操作,低29为都为0,高三位就是c的高三位。就得到了当前的状态了。
当前状态为RUNNING,工作线程为1
1110 0000 00000000 00000000 00000001 RUNNING
& 1110 0000 00000000 00000000 00000000 ~CAPACITY
1110 0000 00000000 00000000 00000000 runStateprivate static int workerCountOf(int c) { return c & CAPACITY; }
得到当前当前线程池中工作线程的数量的方法,其方法与得到状态方法相同。
当前状态为RUNNING,工作线程为1
1110 0000 00000000 00000000 00000001 RUNNING
& 0001 1111 11111111 111111111 11111111 ~CAPACITY
0000 0000 00000000 00000000 00000001 workerCount
这样电脑的可读性更高。速度也就更快