【问题标题】:workerCountOf() method in ThreadPoolExecutor javaThreadPoolExecutor java中的workerCountOf()方法
【发布时间】:2017-01-11 13:50:08
【问题描述】:

我正在尝试理解 ThreadPoolExecutor 类。我发现该类中声明了一些最终变量,但无法理解它们的用途。

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; }

方法前面的 cmets 是我观察到的输出。

现在在ThreadPoolExecutor#execute(runnable) 方法中,

它正在使用If fewer than corePoolSize threads are running的语句进行以下计算

int c = ctl.get();
if (workerCountOf(c) < corePoolSize)

我试图理解,在这种情况下,workerCountOf(c) 的值可能大于 corePoolSize。 如您所见,ctl 的初始值为 RUNNING。

此外,还有一些方法可以原子地增加和减少 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) &amp; CAPACITY) = 0

谁能解释一下创建这些最终变量的原因及其用途?

workerCountOf() 方法实际上如何返回没有正在运行的线程?

我一定是错过了什么。

谢谢

【问题讨论】:

    标签: java multithreading threadpoolexecutor


    【解决方案1】:

    如您所见,Java 使用int ctl 字段来存储池的当前状态和线程数。状态存储在高三位中,所有其他位用于存储线程数。位掩码CAPACITY 用于将它们相互分隔:

    • CAPACITY = 00011111111111111111111111111111
    • ~CAPACITY = 11100000000000000000000000000000

    因此,

    • ctl &amp; CAPACITY 保留低 29 位并将高 3 位归零;结果是当前线程数
    • ctl &amp; ~CAPACITY 保留高三位并将所有其他位归零;结果是池运行状态

    正如您正确注意到的,具有五个线程的运行池具有ctl = (RUNNING + 5),它具有二进制表示形式111000...000101。因此,应用 CAPACITY 掩码会将最高三位归零,并为您提供值 000000...000101,它是 5,而不是 0。

    【讨论】:

      猜你喜欢
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-27
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多