web-dev-qa-db-ja.com

最初の呼び出しに違いがあるshutdownとawaitTermination

違いは何ですか

_ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();
_

そして

_eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
_

shutdown()が本当に理解できません。このメソッドは、以前に送信されたタスクが実行を完了するのを待ちません。 shutdown()は、送信されたが完了していないタスクを終了できることを意味しますか?私はいくつかの例を試しましたが、それはそれを証明しません。例を挙げてください。

33
Amitābha

最初にshutdownを呼び出す必要があります。そうしないと、awaitTerminationが実際にエグゼキューターをシャットダウンしないため、非常に長い時間待機する可能性があります。

Executorがシャットダウンするのを待つのではなく、タスクの完了を待ちたい場合は、invokeAllを使用する必要があります。

45

ドキュメントを読むことは常に役立ちます:

shutdownNow

アクティブに実行中のすべてのタスクを停止し、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。これらのタスクは、このメソッドから戻ったときにタスクキューから排出(削除)されます。

このメソッドタスクのアクティブな実行が終了するまで待機しません。 awaitTerminationを使用して終了します。

アクティブに実行中のタスクの処理を停止するためのベストエフォート型の試みを超える保証はありません。この実装はThread.interrupt()を介してタスクをキャンセルするため、割り込みへの応答に失敗したタスクは終了しません。

shutdown

以前に送信されたタスクは実行されますが、新しいタスクは受け入れられません。すでにシャットダウンされている場合、呼び出しは追加の効果がありません。

このメソッドは、以前に送信されたタスクが実行を完了するのを待ちません。これを行うには、awaitTerminationを使用します。

awaitTermination

シャットダウン要求後、すべてのタスクの実行が完了するまでブロックする、タイムアウトが発生する、または現在のスレッドが中断されるいずれか早い方。

38
S.D.

shutdown は、executorサービスがこれ以上着信タスクを受け取らないことを意味します。

awaitTermination は、シャットダウン要求の後に呼び出されます。

最初にサービスをシャットダウンしてから、スレッドが終了するまでブロックして待機する必要があります。

すべてのスレッドが実行を終了し、awaiTerminationの使用を要求する場合は、タイムアウトパラメーターを十分に大きく設定する必要があります。だからあなたはできる:

eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
    System.err.println("Threads didn't finish in 60000 seconds!");
}

または、次のこともできます。

eService.shutdown();
while (!eService.isTerminated()) {

}

これにより、予期せずに中断されない限り、すべてのスレッドの実行を確実に終了できます。

13
Terry Li

最初のタスクを開始した後、ThreadPoolExecutorは、タスクが終了しても終了しないスレッドを開始します。少なくとも、固定スレッドプールには当てはまります。これが、シャットダウンを呼び出す必要がある理由です。シャットダウン後、ThreadPoolExecutorは新しいタスクを拒否しますが、実行中のタスクが完了するのを待ってから、スレッドの終了を許可します。そのため、shutdwonの後にawaitTerminationが必要です。

2
executorService.execute(runnableTask);  

//executorService.shutdown(); //it will make the executorService stop accepting new tasks
//executorService.shutdownNow(); //tires to destroy the executorService immediately, but it doesn't guarantee that all the running threads will be destroyed at the same time. This method returns list of tasks which are waiting to be processed.
//List<Runnable> notExecutedTasks = executorService.shutdownNow(); //this method returns list of tasks which are waiting to be processed.developer decide what to do with theses tasks?

//one good way to shutdown the executorService is use both of these methods combined with the awaitTermination
executorService.shutdown();
try{
    if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
        executorService.shutdownNow();
    }
}catch (InterruptedException e){
    e.printStackTrace();
}
1
user11656780

主な違い

shutdown()-

1. Not block the calling a thread - means a thread who called the shutdown().
2. Excecutor not accepting new task after calling shutdown().

awaitTermination-

1. Block the calling thread. (as join() method do)

混乱ポイント-shutdown()は以前に送信されたタスクを強制終了しないため、awaitTermination()である理由

また、shutdown()は、以前に送信されたタスクを強制終了せず、送信されたタスクと現在実行中のタスクを続行できることを意味します。

10分のみが送信されたすべてのタスクを完了するのを待ってから、shutdownNow()を呼び出したい場合(---既に何をしているのかを知っている)、呼び出し後にawaitTermination()を使用できるとしますシャットダウン()。

時間制限がない場合、shutdown()は問題ありません。 awaitTermination()は必要ありません。

0
Ashwani Tiwari

Java8 ThreadPool awaitTerminationメソッドから:

    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }

最初にスレッドプールの実行状態をチェックします。また、スレッドプールがシャットダウンされていない場合(実行状態が終了に設定されている場合)、awaitTerminationメソッドはタイムアウトするまで戻りません。これは、最初に待機してからシャットダウンする場合に、長時間待機する理由を説明しています。

0
Jiaqi Guo