1. ホーム
  2. java

Executor ServiceのshutdownとshutdownNowの違いについて

2023-09-20 22:39:37

質問

の基本的な違いを知りたいのですが。 shutdown()shutdownNow() をシャットダウンするための Executor Service ?

私が理解した限りでは

shutdown() を使用する必要があります。 優美 シャットダウンは、実行中で、処理のためにキューに入れられたが開始されていないすべてのタスクが完了することを許可されることを意味します。

shutdownNow() 突然の シャットダウンします。つまり、いくつかの未完成のタスクがキャンセルされ、未着手のタスクもキャンセルされます。私が見逃している暗黙的/明示的な他の何かがありますか?

P.S.: 私は別の質問を エクゼキュータサービスをシャットダウンする方法 に、これと関連した質問がありましたが、私が知りたいこととはちょっと違います。

どのように解決するのですか?

要約すると、そのように考えることができます。

  • shutdown() は、新しいタスクを受け付けないことをエグゼキュータサービスに伝えるだけで、すでに投入されたタスクは実行され続けます。
  • shutdownNow() は同じことをしますし キャンセルしようとする を試み、関連するスレッドに割り込んで既に投入されたタスクをキャンセルします。タスクが割り込みを無視する場合は、注意してください。 shutdownNow と全く同じように動作します。 shutdown .

以下の例を試してみて shutdownshutdownNow を使用して、実行の異なる経路をよりよく理解することができます。

  • shutdown である場合、出力は Still waiting after 100ms: calling System.exit(0)... というのは、実行中のタスクが ではなく が中断され、実行が継続されるからです。
  • shutdownNow である場合、出力は interrupted であり Exiting normally... というのは、実行中のタスクが割り込まれ、それをキャッチして実行を停止する(whileループを中断する)ためです。
  • shutdownNow というように、whileループの中の行をコメントアウトすると、次のようになります。 Still waiting after 100ms: calling System.exit(0)... となります。これは、実行中のタスクによって割り込みが処理されなくなったためです。
public static void main(String[] args) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.submit(new Runnable() {

        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("interrupted");
                    break;
                }
            }
        }
    });

    executor.shutdown();
    if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
        System.out.println("Still waiting after 100ms: calling System.exit(0)...");
        System.exit(0);
    }
    System.out.println("Exiting normally...");
}