您可以使用更復雜的同步機制,如鎖存器,屏障或信號燈,但可以看看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