1. 概要

このチュートリアルでは、 System.exit() Runtime.getRuntime()。halt()と、これら2つのメソッドの比較について説明します。

2. System.exit()

System.exit()メソッドは、実行中のJava仮想マシンを停止します。 ただし、JVMを停止する前に、はシャットダウンシーケンスを呼び出します。これは、正常なシャットダウンとも呼ばれます。 シャットダウンフックの追加の詳細については、この記事を参照してください。

JVMのシャットダウンシーケンスは、最初に登録されているすべてのシャットダウンフックを呼び出し、それらが完了するのを待ちます。 次に、 finalization-on-exit が有効になっている場合は、呼び出されていないすべてのファイナライザーを実行します。 最後に、JVMを停止します。

実際、このメソッドは Runtime.getRuntime()。exit()メソッドを内部的に呼び出します。 引数として整数のステータスコードを取り、voidの戻りタイプを持ちます。

public static void exit(int status)

ステータスコードがゼロ以外の場合は、プログラムが異常停止したことを示しています。

3. Runtime.getRuntime()。halt()

Runtime クラスを使用すると、アプリケーションは、アプリケーションが実行されている環境と対話できます。

実行中のJVM強制的に終了するために使用できるhaltメソッドがあります。

exit メソッドとは異なり、このメソッドはJVMシャットダウンシーケンスをトリガーしません。 したがって、 Halt メソッドを呼び出すと、シャットダウンフックもファイナライザーも実行されません

このメソッドは非静的であり、 System.exit()と同様の署名があります。

public void halt(int status)

exit と同様に、このメソッドのゼロ以外のステータスコードも、プログラムの異常終了を示します。

4. 例

次に、シャットダウンフックを使用して、exitメソッドとhaltメソッドの例を見てみましょう。

簡単にするために、Javaクラスを作成し、シャットダウンフックをstaticブロックに登録します。 また、2つのメソッドを作成します。 1つ目はexitメソッドを呼び出し、2つ目はhalltメソッドを呼び出します。

public class JvmExitAndHaltDemo {

    private static Logger LOGGER = LoggerFactory.getLogger(JvmExitAndHaltDemo.class);

    static {
        Runtime.getRuntime()
          .addShutdownHook(new Thread(() -> {
            LOGGER.info("Shutdown hook initiated.");
          }));
    }

    public void processAndExit() {
        process();
        LOGGER.info("Calling System.exit().");
        System.exit(0);
    }

    public void processAndHalt() {
        process();
        LOGGER.info("Calling Runtime.getRuntime().halt().");
        Runtime.getRuntime().halt(0);
    }

    private void process() {
        LOGGER.info("Process started.");
    }

}

したがって、最初にexitメソッドをテストするために、テストケースを作成しましょう。

@Test
public void givenProcessComplete_whenExitCalled_thenTriggerShutdownHook() {
    jvmExitAndHaltDemo.processAndExit();
}

テストケースを実行して、シャットダウンフックが呼び出されることを確認しましょう。

12:48:43.156 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Process started.
12:48:43.159 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Calling System.exit().
12:48:43.160 [Thread-0] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Shutdown hook initiated.

同様に、halltメソッドのテストケースを作成します。

@Test
public void givenProcessComplete_whenHaltCalled_thenDoNotTriggerShutdownHook() {
    jvmExitAndHaltDemo.processAndHalt();
}

これで、このテストケースも実行して、シャットダウンフックが呼び出されていないことを確認できます。

12:49:16.839 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Process started.
12:49:16.842 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Calling Runtime.getRuntime().halt().

5. exitおよびhaltを使用する場合

前に見たように、 System.exit()メソッドはJVMのシャットダウンシーケンスをトリガーしますが、 Runtime.getRuntime()。halt()はJVMを突然終了します。

オペレーティングシステムのコマンドを使用してこれを行うこともできます。 たとえば、SIGINTまたはCtrl + Cを使用して、 System.exit()やSIGKILLのような正常なシャットダウンをトリガーし、JVMプロセスを突然強制終了できます。

したがって、これらの方法を使用する必要はほとんどありません。 そうは言っても、シェルスクリプトのように、JVMが登録済みのシャットダウンフックを実行したり、特定のステータスコードを呼び出し元に返したりする必要がある場合は、exitメソッドを使用する必要があります。

ただし、適切に設計されていない場合、シャットダウンフックがデッドロックを引き起こす可能性があることに注意することが重要です。 その結果、 exitメソッドは、登録されたシャットダウンフックが終了するまで待機するため、ブロックされる可能性があります。 したがって、これを処理するための可能な方法は、 exit ブロックが発生した場合に、halfメソッドを使用してJVMを強制的に停止することです。

最後に、アプリケーションはこれらのメソッドを誤って使用しないように制限することもできます。 これらのメソッドは両方とも、SecurityManagerクラスのcheckExitメソッドを呼び出します。 したがって、終了および停止操作を禁止するために、アプリケーションは SecurityManager クラスを使用してセキュリティポリシーを作成し、checkExit[からSecurityExceptionをスローできます。 X203X]メソッド。

6. 結論

このチュートリアルでは、例を使用して System.exit()および Runtime.getRuntime()。halt()メソッドを調べました。 さらに、これらのメソッドの使用法とベストプラクティスについても説明しました。

いつものように、この記事の完全なソースコードは、Githubから入手できます。