3

我正在使用 Executor 框架使用线程池(即 newFixedThreadPool)启动多个线程。我使用 threadpool.submit(aThread) 提交要由线程池执行的作业,这工作正常,但是我需要确定所有线程何时完成,以便我可以继续其他处理。我查看了使用 Future.get() 阻塞直到线程完成这里的问题是它阻塞直到结果可用。我还研究了使用连续调用 isTerminated() 方法,然后在发出关闭后休眠以检查所有线程是否已完成,但这对我来说似乎并不整洁。还有另一种更清洁的方法吗?此外,如果任何一个线程中出现异常,我希望能够终止所有其他正在运行的线程,并阻止池中任何排队的线程启动。执行此操作的最佳机制是什么?

期待听到您的回复

TIA

4

2 回答 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,它为它创建的每个线程设置一个“未捕获的异常处理程序”。然后,此异常处理程序可以终止正在运行的任务。

于 2009-09-16T18:13:34.580 回答
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;
    }
  }

}
于 2009-09-16T18:31:08.757 回答