您可以使用更复杂的同步机制,如锁存器,屏障或信号灯,但可以看看ExecutorCompletionService
。这是一个围绕ExecutorService
的轻量级包装,允许您听取第一个完成的任务。下面是一个简单的例子:
final ExecutorService executorService = Executors.newCachedThreadPool();
final ExecutorCompletionService<String> completionService =
new ExecutorCompletionService<String>(executorService);
for (int i = 0; i < 10; ++i) {
completionService.submit(new Task());
}
completionService.take().get();
该代码非常简单。首先你用completionService
包装executorService
。之后你会用它来一个接一个地提交任务。最后一行是至关重要的。它会完成第一项任务并尝试检索结果。如果抛出一个异常,这将在这里再次抛出,包裹着ExecutionException
:
try {
completionService.take().get();
} catch (ExecutionException e) {
e.getCause(); //this was thrown from task!
}
里面catch
块,你能以某种方式处理异常,例如取消剩余的任务或关闭整个线程池。
当然,您可以通过拨打take()
十次来完成所有任务。只要至少有一项任务完成,每个呼叫都会阻止。
您是否试过关闭executos服务并让它中断其他任务?如果这些其他任务不等待/读取,他们仍然可以每隔一段时间检查一次线程中断标志 – radai