(これは、Thilo の以前の削除された回答を私自身の調整で再現する試みです。)
暗黙の無限条件があるため、質問を明確にする必要があると思います...ある時点でエグゼキュータをシャットダウンすることを決定する必要があり、その時点でそれ以上のタスクを受け入れなくなります。あなたの質問は、自分のアプリケーション コードでしか知ることができない、それ以上のタスクが送信されないことがわかるまで待ちたいということを暗示しているようです。
次の回答により、(何らかの理由で) 新しい TPE にスムーズに移行し、現在送信されているすべてのタスクを完了し、新しい TPE への新しいタスクを拒否することができなくなります。それはあなたの質問に答えるかもしれません。@Thiloの可能性もあります。
使用中の目に見えるTPEをどこかに定義していると仮定します。
AtomicReference<ThreadPoolExecutor> publiclyAvailableTPE = ...;
その後、TPE スワップ ルーチンをそのように記述できます。同期メソッドを使用して記述することもできますが、こちらの方が簡単だと思います。
void rotateTPE()
{
ThreadPoolExecutor newTPE = createNewTPE();
// atomic swap with publicly-visible TPE
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(newTPE);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
あるいは、本当に冗談でスレッドプールを強制終了したくない場合は、サブミッター側が拒否されたタスクに対処する必要があるnull
ため、新しい TPE を使用できます。
void killTPE()
{
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(null);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
これはアップストリームの問題を引き起こす可能性があり、呼び出し元はnull
.
また、すべての新しい実行を単純に拒否するダミーの TPE と交換することもできますが、これshutdown()
は TPE を呼び出した場合と同じです。