1192

# 如何维护状态

``````private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
``````

``````//Integer.SIZE = 32
//COUNT_BITS = 29
private static final int COUNT_BITS = Integer.SIZE - 3;
``````

RUNNING-1 << COUNT_BITS1110 0000 0000 0000 0000 0000 0000 0000111
SHUTDOWN0 << COUNT_BITS0000 0000 0000 0000 0000 0000 0000 0000000
STOP1 << COUNT_BITS0010 0000 0000 0000 0000 0000 0000 0000001
TIDYING2 << COUNT_BITS0100 0000 0000 0000 0000 0000 0000 0000010
TERMINATED3 << COUNT_BITS0110 0000 0000 0000 0000 0000 0000 0000011

# CAPACITY如何理解

Ok~.将代码拿出来。我们分析一下这么一行代码。看一下。这个倒是是个啥。

``````private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
``````

``````0010 0000 0000 0000 0000 0000 0000 0000
``````

``````0001 1111 1111 1111 1111 1111 1111 1111
``````

1 << COUNT_BITS(1 << COUNT_BITS) - 1

eumm 最终会得到一个 后面29为都是1 前面3为都是0 的这么一个数。

# 计算线程池数量

``````private static int workerCountOf(int c)  { return c & CAPACITY; }
``````

# 计算线程状态

``````private static int runStateOf(int c)     { return c & ~CAPACITY; }
``````

``````0001 1111 1111 1111 1111 1111 1111 1111
``````

``````1110 0000 0000 0000 0000 0000 0000 0000
``````

# 更新线程池状态和线程数量

``````private static int ctlOf(int rs, int wc) { return rs | wc; }
``````

``````private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
``````

``````1110 0000 0000 0000 0000 0000 0000 0000

0000 0000 0000 0000 0000 0000 0000 0000
``````

``````1110 0000 0000 0000 0000 0000 0000 0000
``````

``````private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
``````

# 为什么这么设计呢

• 如果是两个变量。那么就需要多占有资源。
• 两个变量更加难以维护。在多线程中。为了维护两个变量。势必会占有锁资源。
• 线程池中很多地方都是需要同时判断线程状态和线程数量。这么设计也是为了防止出现判断时候发生不可预期的状态不一致的情况。

# 状态如何切换

``````private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
``````

``````private void advanceRunState(int targetState) {
// assert targetState == SHUTDOWN || targetState == STOP;
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
``````