ThreadPoolExecutor 中的 workerCountOf() 方法 java
workerCountOf() method in ThreadPoolExecutor java
我试图了解 ThreadPoolExecutor class.I 发现其中声明了一些 final 变量 class 并且无法理解它们的用途。
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; //29
private static final int CAPACITY = (1 << COUNT_BITS) - 1; //536870911 00011111111111111111111111111111
// RUN_STATE is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS; //-536870912 11100000000000000000000000000000
private static final int SHUTDOWN = 0 << COUNT_BITS; //0 00000000000000000000000000000000
private static final int STOP = 1 << COUNT_BITS; //536870912 00100000000000000000000000000000
private static final int TIDYING = 2 << COUNT_BITS; //1073741824 01000000000000000000000000000000
private static final int TERMINATED = 3 << COUNT_BITS; //1610612736 01100000000000000000000000000000
以上是最终变量及其二进制和十进制值。
然后我发现了两种使用这些变量的方法:
private static int runStateOf(int c) { return c & ~CAPACITY; } // RUN_STATE & ~CAPACITY = RUN_STATE
private static int workerCountOf(int c) { return c & CAPACITY; } // RUN_STATE & CAPACITY = 0
private static int ctlOf(int rs, int wc) { return rs | wc; }
方法前面的注释是我观察到的输出。
现在在ThreadPoolExecutor#execute(runnable)方法中,
正在做如下计算,语句为If fewer than corePoolSize threads are running
int c = ctl.get();
if (workerCountOf(c) < corePoolSize)
我试图理解,在这种情况下,workerCountOf(c) 的值可以大于 corePoolSize。
可以看到ctl的初始值为运行.
此外,还有一些方法可以自动增加和减少 ctl 值,
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
现在假设,5 个线程是 运行,所以 ctl = RUNNING + 5
,
即便如此 workerCountOf(ctl.get()) = 0
,
如((RUNNING+5) & CAPACITY) = 0
.
谁能解释一下创建这些 final 变量的原因及其用途?
workerCountOf() 方法如何实际返回 运行 个线程?
我一定是漏了什么。
谢谢
如您所见,Java 使用 int ctl
字段来存储池的当前状态和线程数。状态存储在高三位,所有其他位用于存储线程数。位掩码 CAPACITY
用于将它们彼此分开:
CAPACITY = 00011111111111111111111111111111
~CAPACITY = 11100000000000000000000000000000
因此,
ctl & CAPACITY
保留低29位,高三位归零;结果是当前线程数
ctl & ~CAPACITY
保留高三位并将所有其他位清零;结果是池 运行 状态
正如您正确注意到的那样,具有五个线程的 运行ning 池有 ctl = (RUNNING + 5)
,具有二进制表示 111000...000101
。因此,应用 CAPACITY
掩码会将最高三位归零并给出值 000000...000101
,即 5,而不是 0。
我试图了解 ThreadPoolExecutor class.I 发现其中声明了一些 final 变量 class 并且无法理解它们的用途。
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; //29
private static final int CAPACITY = (1 << COUNT_BITS) - 1; //536870911 00011111111111111111111111111111
// RUN_STATE is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS; //-536870912 11100000000000000000000000000000
private static final int SHUTDOWN = 0 << COUNT_BITS; //0 00000000000000000000000000000000
private static final int STOP = 1 << COUNT_BITS; //536870912 00100000000000000000000000000000
private static final int TIDYING = 2 << COUNT_BITS; //1073741824 01000000000000000000000000000000
private static final int TERMINATED = 3 << COUNT_BITS; //1610612736 01100000000000000000000000000000
以上是最终变量及其二进制和十进制值。
然后我发现了两种使用这些变量的方法:
private static int runStateOf(int c) { return c & ~CAPACITY; } // RUN_STATE & ~CAPACITY = RUN_STATE
private static int workerCountOf(int c) { return c & CAPACITY; } // RUN_STATE & CAPACITY = 0
private static int ctlOf(int rs, int wc) { return rs | wc; }
方法前面的注释是我观察到的输出。
现在在ThreadPoolExecutor#execute(runnable)方法中,
正在做如下计算,语句为If fewer than corePoolSize threads are running
int c = ctl.get();
if (workerCountOf(c) < corePoolSize)
我试图理解,在这种情况下,workerCountOf(c) 的值可以大于 corePoolSize。 可以看到ctl的初始值为运行.
此外,还有一些方法可以自动增加和减少 ctl 值,
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
现在假设,5 个线程是 运行,所以 ctl = RUNNING + 5
,
即便如此 workerCountOf(ctl.get()) = 0
,
如((RUNNING+5) & CAPACITY) = 0
.
谁能解释一下创建这些 final 变量的原因及其用途?
workerCountOf() 方法如何实际返回 运行 个线程?
我一定是漏了什么。
谢谢
如您所见,Java 使用 int ctl
字段来存储池的当前状态和线程数。状态存储在高三位,所有其他位用于存储线程数。位掩码 CAPACITY
用于将它们彼此分开:
CAPACITY = 00011111111111111111111111111111
~CAPACITY = 11100000000000000000000000000000
因此,
ctl & CAPACITY
保留低29位,高三位归零;结果是当前线程数ctl & ~CAPACITY
保留高三位并将所有其他位清零;结果是池 运行 状态
正如您正确注意到的那样,具有五个线程的 运行ning 池有 ctl = (RUNNING + 5)
,具有二进制表示 111000...000101
。因此,应用 CAPACITY
掩码会将最高三位归零并给出值 000000...000101
,即 5,而不是 0。