ThreadPoolExecutor挂起

时间:2013-11-23 01:16:50

标签: java multithreading threadpool threadpoolexecutor

尝试调试竞争条件,其中一个应用程序的轮询器线程永远不会返回,导致将来的轮询器永远不会被调度。用抽象的术语来隐藏我们的业务逻辑,同时捕获问题,这就是我们的代码路径。

我们必须更新远程服务器中资源Y的某些状态X.我们有一个资源管理器,它可以更改资源状态并更新X作为更改的副作用。该经理持续轮询资源,当它认为资源更新时,它使用ThreadPoolExecutor来完成工作。此线程池执行程序具有合理大小的阻塞队列,但最小线程数相当少。来自线程转储的挂起发生在invokeAll调用(以及其他内容)

我们有理由相信此池执行程序中的核心/最大线程数正忙于执行其他操作(如果您愿意,可以使用更多资源状态更新)。

由于invokeAll返回我们等待的期货,问题是invokeAll挂起,即使执行程序使用的阻塞数据结构足够大,可以接受通过invokeAll传递的工作,但是没有足够的线程可用? / p>

1 个答案:

答案 0 :(得分:3)

正如其他用户指出的那样,没有一些代码(甚至伪代码),更清楚地了解什么"陈述 X "是,什么"资源 Y "是的,这里的任何人几乎不可能提供一个明智的答案。简而言之,您需要一个SSCCE。不过,我会在这里尽我所能;-)。如果您发布代码和/或提供更多信息,我会相应地更新我的答案。

来自Java 7 ExecutorService#invokeAll javadoc

  

执行给定的任务,在完成所有任务后返回持有其状态和结果的Futures列表。对于返回列表的每个元素,Future.isDone()都为true。请注意,已完成的任务可能正常终止或通过抛出异常终止。如果在此操作正在进行时修改了给定集合,则此方法的结果未定义。

根据您的描述(而且,由于缺乏细节,我无法确定),您的一个工作线程正在悬空。由于您正在调用invokeAll(...),因此执行程序正在挂起,因为它正在等待挂起的线程完成。但它永远不会。现在,至于为什么你会得到一个挂起的线程,这是一个完全不同的问题,我们肯定需要看到一些代码。 HTH。