转载

JDK中使用32位的int类型包装两个不相关状态

也许是因为一个int类型的数值有32位,但通常只会用到低字节的部分,高位的部分通常是浪费的。

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;
原文  https://segmentfault.com/a/1190000019943236
正文到此结束
Loading...