在JDK中想保证操作的原子性的选择是很少的,大多是使用Atomic包装类。巧妙使用int类型的高位、低位表达两种不中的状态,此方式可以保证两种状态的原子性。
JDK中ThreadPoolExecutor使用一个AtomicInteger表达了两种不相关的状态控制:
ctl, is an atomic integer packing two conceptual fields
- workerCount, indicating the effective number of threads
- runState, indicating whether running, shutting down etc
用高位的三个字节表示线程池的状态,其他的字节表达工作线程数。
packing & unpacking 算法如下:
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;
// runState is stored in the high-order bits
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;
// 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; }
PS:负数的原码是去掉最高的符号位的其他位, 后面的位取反为反码,反码+1后为补码。
算法为: 负数的绝对值(原码)= 取反(补码-1)
位运算:
与运算符:& 相同位都为1则取1,否则取0;
或运算符:| 相同位有一个为1则取1,都为0才取0;
异或运算符:^ 相同则取1,不同则取0;常用:(m ^ n) ^ n = m;(m ^ n) ^ m = n;
取反运算符:~ 相同位0取1,1取0;
Created by 苏亚强(sueeing@126.com) on 2019/8/2.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。