私が思いつくことができる唯一の洗練されていない解決策は、ThreadPoolExecutor を直接使用し、その getPoolSize() を時々クエリすることです。それを行うより良い方法は本当にありませんか?
shutdown() ,
適切な順序でawaitTermination()and shutdownNow()
メソッドを使用する必要があります。
shutdown()
: 以前にサブミットされたタスクが実行される通常のシャットダウンを開始しますが、新しいタスクは受け入れられません。
awaitTermination()
: シャットダウン要求の後、すべてのタスクが実行を完了するか、タイムアウトが発生するか、または現在のスレッドが中断されるかのいずれかが最初に発生するまでブロックします。
shutdownNow()
: アクティブに実行中のすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。
ExecutorServiceのOracleドキュメントページからの推奨される方法:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
以下のように、タスクの完了に長時間かかる場合は、 if 条件を while 条件に置き換えることができます。
変化する
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
に
while(!pool.awaitTermination(60, TimeUnit.SECONDS)) {
Thread.sleep(60000);
}
join()
で他の代替手段を参照できます (スタンドアロン スレッドで使用できるを除く)。
すべてのスレッドが Java での作業を完了するまで待ちます