すべてのスレッドがいつ完了するかを把握し、例外に対処する
-
07-07-2019 - |
質問
Executorフレームワークを使用して、スレッドプール、つまりnewFixedThreadPoolを使用して複数のスレッドを開始しています。 threadpool.submit(aThread)を使用して、スレッドプールによって実行されるジョブを送信しますが、これは正常に機能しますが、他の処理を続行できるように、すべてのスレッドが完了したかどうかを判断する必要があります。スレッドが完了するまでブロックするFuture.get()を使用することを検討しましたが、結果が利用可能になるまでブロックするという問題があります。また、すべてのスレッドが完了したかどうかを確認するためにシャットダウンを発行した後、isTerminated()メソッドを連続的に呼び出してスリープする方法も検討しましたが、これは適切ではないようです。これに別のよりクリーンな方法はありますか?また、いずれかのスレッドで例外が発生した場合、実行中の他のすべてのスレッドを終了し、プール内のキューに入れられたスレッドの開始を停止できるようにします。これを行うための最良のメカニズムは何ですか?
返信をお待ちしています
TIA
解決
これにアプローチするよりクリーンな方法の1つは、送信されるタスクを変更することです。各タスクにコールバックを登録することにより、メインスレッドによるポーリングなしで正常終了または例外を通知できます。
または、その例に従って、任意の 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;
}
}
}
他のヒント
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
タスクが例外で失敗したときに通知する限り。 ThreadFactory &quot; uncaught Exception handler&quot;を設定するExecutorServiceに作成するスレッドごとに。この例外ハンドラは、実行中のタスクを終了できます。