Runtime.getRuntime (). Halt () vs System.exit () in Java

1. Übersicht

In diesem Tutorial werden wir uns mit System.exit () , Runtime.getRuntime (). Halt () und dem Vergleich dieser beiden Methoden befassen .

2. System.exit ()

Die Methode System.exit () stoppt die laufende Java Virtual Machine . Bevor die JVM gestoppt wird, wird die Abschaltsequenz aufgerufen , die auch als ordnungsgemäßes Herunterfahren bezeichnet wird. Weitere Informationen zum Hinzufügen von Shutdown-Hooks finden Sie in diesem Artikel.

Die Shutdown-Sequenz von JVM ruft zuerst alle registrierten Shutdown-Hooks auf und wartet, bis sie abgeschlossen sind. Anschließend werden alle nicht aufgerufenen Finalizer ausgeführt, wenn Finalization-on-Exit aktiviert ist. Schließlich wird die JVM angehalten.

Diese Methode ruft tatsächlich die Methode Runtime.getRuntime (). Exit () intern auf. Es verwendet einen ganzzahligen Statuscode als Argument und hat einen ungültigen Rückgabetyp:

public static void exit(int status)

Wenn der Statuscode ungleich Null ist, zeigt dies an, dass das Programm abnormal gestoppt wurde.

3. Runtime.getRuntime (). Halt ()

Mit der Runtime- Klasse kann eine Anwendung mit der Umgebung interagieren, in der die Anwendung ausgeführt wird.

Es verfügt über eine Stopp- Methode, mit der die laufende JVM zwangsweise beendet werden kann .

Im Gegensatz zur Exit- Methode löst diese Methode die JVM-Shutdown-Sequenz nicht aus. Daher werden weder die Shutdown-Hooks noch die Finalizer ausgeführt, wenn wir die halt- Methode aufrufen .

Diese Methode ist nicht statisch und hat eine ähnliche Signatur wie System.exit () :

public void halt(int status)

Ähnlich wie beim Beenden zeigt auch der Statuscode ungleich Null in dieser Methode eine abnormale Beendigung des Programms an.

4. Beispiel

Schauen wir uns nun ein Beispiel für Exit- und Stopp- Methoden mit Hilfe eines Shutdown-Hooks an.

Um es einfach zu halten, erstellen wir eine Java-Klasse und registrieren einen Shutdown-Hook in einem statischen Block. Außerdem erstellen wir zwei Methoden. Der erste ruft die Exit- Methode auf und der zweite die Stopp- Methode:

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."); } }

Um zuerst die Exit-Methode zu testen, erstellen wir einen Testfall:

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

Lassen Sie uns nun den Testfall ausführen und sehen, dass der Shutdown-Hook aufgerufen wird:

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.

In ähnlicher Weise erstellen wir einen Testfall für die Stopp- Methode:

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

Jetzt können wir auch diesen Testfall ausführen und feststellen, dass der Shutdown-Hook nicht aufgerufen wird:

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. Wann verwenden Sie exit und halt?

Wie wir bereits gesehen haben, löst die System.exit () -Methode die Abschaltsequenz von JVM aus, während Runtime.getRuntime (). Halt () die JVM abrupt beendet.

Wir können dies auch mithilfe von Betriebssystembefehlen tun. Zum Beispiel können wir SIGINT oder Strg + C verwenden, um das ordnungsgemäße Herunterfahren auszulösen, wie System.exit () und SIGKILL, um den JVM-Prozess abrupt abzubrechen .

Daher müssen wir diese Methoden selten anwenden. Allerdings müssen wir möglicherweise die Exit- Methode verwenden, wenn die JVM die registrierten Shutdown-Hooks ausführen oder einen bestimmten Statuscode an den Aufrufer zurückgeben muss, wie bei einem Shell-Skript.

Es ist jedoch wichtig zu beachten, dass der Abschalthaken einen Deadlock verursachen kann, wenn er nicht richtig konstruiert ist. Folglich kann die Exit- Methode blockiert werden, während sie wartet, bis die registrierten Shutdown-Hooks beendet sind. Eine Möglichkeit, dies zu beheben, besteht darin, die Halt- Methode zu verwenden, um JVM zum Anhalten zu zwingen, falls Exit- Blöcke vorhanden sind.

Schließlich kann eine Anwendung diese Methoden auch von einer versehentlichen Verwendung abhalten. Beide Methoden rufen die checkExit- Methode der SecurityManager- Klasse auf. Um die Exit- und Stopp- Vorgänge zu verbieten , kann eine Anwendung mithilfe der SecurityManager- Klasse eine Sicherheitsrichtlinie erstellen und die SecurityException aus der checkExit- Methode auslösen .

6. Fazit

In diesem Tutorial haben wir uns anhand eines Beispiels die Methoden System.exit () und Runtime.getRuntime (). Halt () angesehen . Darüber hinaus haben wir auch über die Verwendung und die Best Practices dieser Methoden gesprochen.

Wie üblich ist der vollständige Quellcode dieses Artikels auf Github verfügbar.