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

1. Vue d'ensemble

Dans ce didacticiel, nous examinerons System.exit () , Runtime.getRuntime (). Halt () et comment ces deux méthodes se comparent.

2. System.exit ()

La méthode System.exit () arrête la machine virtuelle Java en cours d'exécution . Mais, avant d'arrêter la JVM, il appelle la séquence d'arrêt , également appelée arrêt ordonné. Veuillez consulter cet article pour en savoir plus sur l'ajout de hooks d'arrêt.

La séquence d'arrêt de JVM appelle d'abord tous les hooks d'arrêt enregistrés et attend qu'ils se terminent. Ensuite, il exécute tous les finaliseurs non sollicités si la finalisation à la sortie est activée. Enfin, il arrête la JVM.

Cette méthode, en fait, appelle la méthode Runtime.getRuntime (). Exit () en interne. Il prend un code d'état entier comme argument et a un type de retour void :

public static void exit(int status)

Si le code d'état est différent de zéro, cela indique que le programme s'est arrêté anormalement.

3. Runtime.getRuntime (). Halt ()

La classe Runtime permet à une application d'interagir avec l'environnement dans lequel l'application s'exécute.

Il dispose d'une méthode d' arrêt qui peut être utilisée pour forcer l'arrêt de la JVM en cours d'exécution .

Contrairement à la méthode de sortie , cette méthode ne déclenche pas la séquence d'arrêt JVM. Par conséquent, ni les hooks d'arrêt ni les finaliseurs ne sont exécutés lorsque nous appelons la méthode halt .

Cette méthode n'est pas statique et a une signature similaire à System.exit () :

public void halt(int status)

Similaire à exit , le code d'état différent de zéro dans cette méthode indique également l'arrêt anormal du programme.

4. Exemple

Voyons maintenant un exemple de méthodes de sortie et d' arrêt , à l'aide d'un hook d'arrêt.

Pour faire simple, nous allons créer une classe Java et enregistrer un hook d'arrêt dans un bloc statique . Nous allons également créer deux méthodes; le premier appelle la méthode exit et le second appelle la méthode halt :

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

Donc, pour tester d'abord la méthode de sortie, créons un cas de test:

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

Exécutons maintenant le cas de test et voyons que le hook d'arrêt est appelé:

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.

De même, nous allons créer un cas de test pour la méthode halt :

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

Maintenant, nous pouvons également exécuter ce cas de test et voir que le hook d'arrêt n'est pas appelé:

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. Quand utiliser Quitter et arrêter

Comme nous l'avons vu précédemment, la méthode System.exit () déclenche la séquence d'arrêt de la JVM, tandis que Runtime.getRuntime (). Halt () arrête brusquement la JVM.

Nous pouvons également le faire en utilisant les commandes du système d'exploitation. Par exemple, nous pouvons utiliser SIGINT ou Ctrl + C pour déclencher l'arrêt ordonné comme System.exit () et SIGKILL pour tuer brusquement le processus JVM.

Par conséquent, nous avons rarement besoin d'utiliser ces méthodes. Cela dit, nous pouvons avoir besoin d'utiliser la méthode exit lorsque nous avons besoin de la JVM pour exécuter les hooks d'arrêt enregistrés ou renvoyer un code d'état spécifique à l'appelant, comme avec un script shell.

Cependant, il est important de noter que le hook d'arrêt peut provoquer un blocage s'il n'est pas conçu correctement. Par conséquent, la méthode de sortie peut être bloquée en attendant la fin des hooks d'arrêt enregistrés. Donc, un moyen possible de résoudre ce problème est d'utiliser la méthode d' arrêt pour forcer l' arrêt de la JVM, au cas où la sortie se bloque.

Enfin, une application peut également limiter l'utilisation accidentelle de ces méthodes. Ces deux méthodes appellent la méthode checkExit de la classe SecurityManager . Ainsi, pour interdire les opérations de sortie et d' arrêt , une application peut créer une stratégie de sécurité à l'aide de la classe SecurityManager et lancer l' exception SecurityException à partir de la méthode checkExit .

6. Conclusion

Dans ce didacticiel, nous avons examiné les méthodes System.exit () et Runtime.getRuntime (). Halt () à l'aide d'un exemple. De plus, nous avons également parlé de l'utilisation et des meilleures pratiques de ces méthodes.

Comme d'habitude, le code source complet de cet article est disponible à l'adresse over sur Github.