【问题标题】:ThreadPoolExecutor hangsThreadPoolExecutor 挂起
【发布时间】:2013-12-08 01:38:14
【问题描述】:

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

我们必须更新远程服务器中资源 Y 的某些状态 X。我们有一个资源管理器,它更改资源状态并更新 X 作为更改的副作用。该经理不断地轮询资源,当它认为资源已更新时,它使用ThreadPoolExecutor 来完成工作。这个线程池执行器有一个合理大小的阻塞队列,但最大线程数相当少。线程转储的挂起本身发生在 invokeAll 调用中(除其他外)

我们有理由相信这个池执行器中的核心/最大线程数正忙于做其他事情(如果您愿意,可以更新更多资源状态)。

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

【问题讨论】:

    标签: java multithreading threadpool threadpoolexecutor


    【解决方案1】:

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

    来自Java 7 ExecutorService#invokeAll javadoc:

    执行给定的任务,返回一个 Futures 列表,在所有完成后保存它们的状态和结果。 Future.isDone() 对于返回列表的每个元素都是 true。请注意,已完成的任务可能已经正常终止,也可能通过引发异常终止。如果在此操作进行时修改了给定的集合,则此方法的结果是不确定的。

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

    【讨论】:

      猜你喜欢
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 2011-09-12
      • 2012-05-09
      • 2014-01-17
      • 2012-12-20
      相关资源
      最近更新 更多