1

在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.


邓邓
142 声望5 粉丝