知道何时所有线程完成并处理异常

3
我正在使用Executor框架来启动多个线程,使用线程池即newFixedThreadPool。我使用threadpool.submit(aThread)将要执行的作业提交给线程池,这很好用,但是我需要确定何时所有线程都完成,以便我可以继续处理其他事情。我考虑使用Future.get(),它会阻塞直到线程完成,但问题在于它会一直阻塞直到结果可用。我还尝试不断调用isTerminated()方法并在发出关闭指令后休眠以检查是否所有线程都已完成,但这对我来说并不简洁。有没有另一种更干净的方法?此外,如果任何一个线程引发异常,我希望能够终止所有其他正在运行的线程,并停止池中排队的任何线程开始运行。最好的机制是什么?期待您的回复。谢谢!
2个回答

7

使用ExecutorService#shutdown(),然后使用ExecutorService#awaitTermination()

例如:

ExecutorService service = Executors.newCachedThreadPool();
service.submit(...);
service.submit(...);
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

// All tasks have now finished

如果需要在任务遇到异常时通知您,您需要向ExecutorService提供一个ThreadFactory,为它创建的每个线程设置一个"未捕获异常处理程序"。这个异常处理程序可以终止正在运行的任务。


1

处理这个问题的一种较为简洁的方法是修改提交的任务。通过为每个任务注册回调函数,它可以在没有主线程轮询的情况下通知正常完成或异常。

您可以编写一个简单的包装器来实现这一点 适用于任何Runnable

或者,按照该示例,您可以扩展这个想法来包装任何Callable

class CallbackTask<T>
  implements Callable<T>
{

  private final Callable<? extends T> task;

  private final Callback<T> callback;

  CallbackTask(Callable<? extends T> task, Callback<T> callback)
  {
    this.task = task;
    this.callback = callback;
  }

  public T call()
    throws Exception
  {
    try {
      T result = task.call();
      callback.complete(result);
      return result;
    }
    catch (Exception ex) {
      callback.failed(ex);
      throw ex;
    }
  }

}

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