也许是因为一个int类型的数值有32位,但通常只会用到低字节的部分,高位的部分通常是浪费的。
JDK中ThreadPoolExecutor使用一个AtomicInteger表达了两种不相关的状态控制:
ctl, is an atomic integer packing two conceptual fields
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;