【问题标题】:Implementing thread timeout in executor service在执行器服务中实现线程超时
【发布时间】:2012-09-06 15:02:58
【问题描述】:

所以现在我有一个相当基本的 Executor 服务,我用它来将我的程序分成线程,如下所示:

ExecutorService threadPool = Executors.newFixedThreadPool(12);
for (int i = 0; i < objectArray.length; i++) {
    threadPool.submit(new ThreadHandler(objectArray[i], i));
          // The i is used elsewhere
}

我想知道是否有检测/关闭“崩溃”或“冻结”线程的好方法?我查看了文档,但它似乎完全不适合我使用它的方式......

有人可以帮我解决这个问题吗?谢谢

【问题讨论】:

  • 您可以保留对您提交的 ThreadHandlers 的引用并定期检查它们。

标签: java multithreading


【解决方案1】:

threadPool.submit 返回Future&lt;T&gt; 对象。所以使用这个未来的对象,你可以处理你的任务执行。 通过使用isCancelled() and isDone 方法,您可以检查任务是否已取消或完成。更多的get() 是阻塞调用,它在解释、取消或执行异常时抛出异常。

List<Future<?>> list = new ArrayList<Future<?>>();
for (int i = 0; i < objectArray.length; i++) {
    Future<?> task=threadPool.submit(new ThreadHandler(objectArray[i], i));
          // The i is used elsewhere
    list.add(task);
}
for(Future future : list){
   try{
       future.get();
   }catch(CancellationException cx){
   ...
   }catch(ExecutionException ex){
   ...
   }catch(InterruptedException ix){
   ...
   }

}

【讨论】:

  • 你认为你可以给我看一个实现的例子吗?我对如何使用 Future 来实现这一点有点困惑。我想我知道如何使用 isCancelled / isDone,但它们不会检测到某些东西是否由于某种原因而崩溃/停止。
  • 很棒的解决方案,这很好地解释了如何处理我的问题。
  • @A_Elric 您如何解决冻结线程的问题。 get() 阻塞,直到线程完成并且冻结的线程永远不会返回任何结果。所以脚本正在等待...
【解决方案2】:

您可以选择使用ExecutorCompletionService。您通过其submit 方法执行任务,然后使用poll(long timeout, TimeUnit unit) 方法让一个单独的线程等待完成。以异常终止的任务将返回一个Futureget() 将抛出一个ExecutionException

使用超时,您还可以检测到任何任务返回之前的时间过长;然而,这种行为的实用性很大程度上取决于您的设置。

【讨论】:

  • 我也很喜欢这个答案,因为它向我介绍了 ExecutorCompletionService,这也是处理这个问题的好方法。
【解决方案3】:

您所能做的就是中断已取消的任务。您可以使用 ScheduledExecutorService 安排要取消的任务

如果您的代码不支持中断,则需要对其进行修复以使其支持。这很难以接近可靠的方式以编程方式解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多