ThreadPoolExecutor#getActiveCount()方法的精度有多高?

6

ThreadPoolExecutor#getActiveCount()的Javadocs说,该方法“返回正在执行任务的线程的近似数量。”

是什么造成了这个数字是近似值而不是精确值?它会低估或高估活跃线程吗?

以下是该方法:

/**
 * Returns the approximate number of threads that are actively
 * executing tasks.
 *
 * @return the number of threads
 */
public int getActiveCount() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        int n = 0;
        for (Worker w : workers)
            if (w.isLocked())
                ++n;
        return n;
    } finally {
        mainLock.unlock();
    }
}
1个回答

12

该方法接受工人列表并计算正在被锁定的工人数。

当计数到达列表末尾时,先前计数的某些工人可能已完成任务。(或者一些未使用的工人可能已经被分配了任务。)

但是,作为客户端,您不应该依赖这种知识,只需要知道它是一个尽力而为的近似值。请注意,这种“不准确性”不是因为实现粗心而产生的,它存在于每个真正的多线程系统中。在这种系统中,没有全局的“当前时刻”。即使您停止所有工人进行计数,当您返回结果时,它可能不准确。


这意味着你得到的数字可能会大于实际活动线程数(如果有些线程在你完成计数时已经结束)。 - eric
1
@eric 它可能更大或更小。没有办法确定。实际上,在多线程系统中,这个问题本身就没有太多意义。 - biziclop
谢谢,SO让我等四分钟后才能接受这个答案 :-) - eric
2
另一种说法是:该方法可能做到的最好的事情就是返回一个在某个时间点上是正确的结果,但在调用者基于该结果做出决策之前,这个时间点已经过去了。 - Solomon Slow
@jameslarge 是的,尽管在这种情况下,可能甚至没有一个时刻结果是正确的,因为工作人员在迭代进行时不会停止。在一个特别不幸的场景中,即使在每个时刻都有恰好“池大小-1”个线程在工作,你甚至可能得到0的计数。 - biziclop
2
当我写下“方法可能做到的最好”,我在想你所说的“停止所有工作人员进行计数”。从理论上讲是可能的,但不明智。我试图引起注意,当我们尝试证明多线程程序的正确性时,我们可能必须接受比单线程程序更弱的“正确性”。例如,无法证明无锁队列中项目出现的顺序,当生产者之间没有“先于发生”的关系时。或者,正如你所说,“没有全局的当前时刻”。 - Solomon Slow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接