ラッチ、バリア、またはセマフォなどのより複雑な同期メカニズムを使用できますが、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();
コードはかなりシンプルです。まず、executorService
をcompletionService
で囲みます。後でタスクを順番に送信するために使用します。最後の行が重要です。完了した最初のタスクが実行され、結果を取得しようとします。それが例外をスローした場合、ここで再スローExecutionException
でラップされます。catch
ブロック内の
try {
completionService.take().get();
} catch (ExecutionException e) {
e.getCause(); //this was thrown from task!
}
あなたが何らかの形で、例えば、例外を処理することができます残りのタスクを取り消したり、スレッドプール全体をシャットダウンしたりします。
もちろん、take()
に10回コールすると、すべてのタスクが完了するまで待つことができます。少なくとも1つのタスクが終了している限り、各コールはブロックされます。
あなたはexecutosサービスをシャットダウンして、他のタスクを中断してみましたか?これらの他のタスクが待機/読んでいない場合は、スレッドの中断フラグを毎時確認してから – radai