【问题标题】:Java Thread Pool Executor MonitoringJava 线程池执行器监控
【发布时间】:2012-05-09 05:29:52
【问题描述】:

Java SE 6 文档中的 ThreadPoolExecutor 类具有以下method

public int getActiveCount()

返回大概的线程数 正在积极执行任务。

这里近似主动执行是什么意思?

如果在致电getActiveCount()之前、期间和之后,是否有任何保证

  1. N 个线程已从池中分配用于任务执行,并且
  2. 这些 N 个线程中没有一个可用于进一步的任务分配,

getActiveCount() 返回的整数正好是N

如果getActiveCount()不提供此保证,是否有任何其他方式可以更准确地获取此信息?

之前的 SO 问题:

我查看了Thread Pool Executor Monitoring RequirementHow to tell if there is an available thread in a thread pool in java,但他们没有回答我的问题。

【问题讨论】:

  • ThreadPoolExecutor 是否有任何特定的必要性,在这种情况下是否可以使用诸如 Executors.newFixedThreadPool(N) 之类的工厂方法?
  • @posdef,我需要一个有界任务队列。 newFixedThreadPool() 有可能吗?
  • 嗯,你得到的是一个执行器服务,它有一个你定义的大小的线程池。检查 javadocs 是否满足您的需求。我发现它们确实非常有用:)

标签: java monitoring threadpool


【解决方案1】:

之所以是近似是因为在计算过程中数字可能会发生变化;你是多线程的。在计算完成之前,现在可以有不同数量的线程处于活动状态(检查时处于非活动状态的线程现在处于活动状态)。

当你说“特定的时间实例”时......这并不意味着什么。计算不是即时的。考虑到池的流体/动态性质,您得到的数字是最好的答案。

如果 偶然 计算开始并完成,而池中的线程都没有改变状态,那么是的,这个数字是“准确的”,但只有在池中的线​​程改变状态之前,这意味着它可能只有 1 毫秒(或更短)的“精确”。

【讨论】:

  • 线程中没有“状态变化”。我已经适当地编辑了这个问题。
  • 我的回答仍然适用;最后一段将涵盖您的情况。前面的段落描述了为什么文档说 approximate - 在许多情况下,您的特定状态不存在,在计算时池没有变化。
  • Brian -- 我认为在当前的JDK实现中,实际上有一个全局锁,这意味着线程数在枚举它们时不会改变。但 API 定义显然留下了在其他/未来实现中不会出现这种情况的可能性。
  • @Neil - 是的,有了这些你真的不关心特定 JVM 的当前实现;我什至没有去看。
【解决方案2】:

我认为您可能会通过引入 ThreadPoolExecutor 的实现中并不存在的“重新加入池”的概念来混淆事情。

每个工作线程都在不断地等待任务(它实际上位于阻塞队列的顶部)。每个任务进入其队列,该工作人员被“锁定”,然后运行任何任务前内务处理,然后运行实际任务,然后是任务后内务处理,然后工作人员被“解锁”。

activeCount() 为您提供处于“锁定”状态的线程数:请注意,这意味着它们实际上可以在调用 activeCount() 的精确时刻进行“内务处理”,但这将被视为“活动” ',必须有一个实际涉及的任务,或者即将执行、当前执行或刚刚执行。

这是否等同于您“重新加入池”的概念我不确定 - 正如我所说,您似乎在发明一个概念,从 ThreadPoolExecutor 的角度来看严格来说并不存在。

【讨论】:

  • 这清楚地解释了actively executing 部分。感谢您指出不一致之处。我已更新问题以将其删除。