Runtime.getRuntime (). Halt () rispetto a System.exit () in Java

1. Panoramica

In questo tutorial, esamineremo System.exit () , Runtime.getRuntime (). Halt () e come questi due metodi si confrontano tra loro.

2. System.exit ()

Il metodo System.exit () arresta la Java Virtual Machine in esecuzione . Ma, prima di arrestare la JVM, chiama la sequenza di arresto , nota anche come chiusura ordinata. Fare riferimento a questo articolo per saperne di più sull'aggiunta di hook di spegnimento.

La sequenza di chiusura di JVM richiama prima tutti gli hook di chiusura registrati e attende che vengano completati. Quindi, esegue tutti i finalizzatori non richiamati se la finalizzazione all'uscita è abilitata. Infine, arresta la JVM.

Questo metodo, infatti, chiama internamente il metodo Runtime.getRuntime (). Exit () . Accetta un codice di stato intero come argomento e ha un tipo di ritorno void :

public static void exit(int status)

Se il codice di stato è diverso da zero, indica che il programma è stato interrotto in modo anomalo.

3. Runtime.getRuntime (). Halt ()

La classe Runtime consente a un'applicazione di interagire con l'ambiente in cui è in esecuzione l'applicazione.

Ha un metodo di arresto che può essere utilizzato per terminare forzatamente la JVM in esecuzione .

A differenza del metodo di uscita , questo metodo non attiva la sequenza di chiusura della JVM. Pertanto, gli hook di chiusura né i finalizzatori vengono eseguiti quando chiamiamo il metodo halt .

Questo metodo non è statico e ha una firma simile a System.exit () :

public void halt(int status)

Analogamente all'uscita , il codice di stato diverso da zero in questo metodo indica anche la chiusura anomala del programma.

4. Esempio

Vediamo ora un esempio di metodi exit e halt , con l'aiuto di un hook di spegnimento.

Per mantenerlo semplice, creeremo una classe Java e registreremo un hook di chiusura in un blocco statico . Inoltre, creeremo due metodi; il primo chiama il metodo exit e il secondo chiama il metodo 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."); } }

Quindi, per testare prima il metodo di uscita, creiamo un caso di test:

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

Eseguiamo ora il test case e vediamo che l'hook shutdown viene chiamato:

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.

Allo stesso modo, creeremo un test case per il metodo halt :

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

Ora, possiamo eseguire anche questo test case e vedere che l'hook shutdown non viene chiamato:

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. Quando utilizzare exit e halt

Come abbiamo visto in precedenza, il metodo System.exit () attiva la sequenza di arresto di JVM, mentre Runtime.getRuntime (). Halt () termina la JVM bruscamente.

Possiamo farlo anche utilizzando i comandi del sistema operativo. Ad esempio, possiamo usare SIGINT o Ctrl + C per attivare l'arresto ordinato come System.exit () e SIGKILL per terminare bruscamente il processo JVM.

Pertanto, raramente abbiamo bisogno di utilizzare questi metodi. Detto questo, potrebbe essere necessario utilizzare il metodo exit quando è necessario che la JVM esegua gli hook di chiusura registrati o restituisca un codice di stato specifico al chiamante, come con uno script di shell.

Tuttavia, è importante notare che l'hook shutdown può causare un deadlock, se non progettato correttamente. Di conseguenza, il metodo di uscita può essere bloccato mentre attende il termine degli hook di arresto registrati. Quindi, un modo possibile per occuparsene è usare il metodo halt per forzare l' arresto di JVM, nel caso in cui blocchi di uscita .

Infine, un'applicazione può anche limitare questi metodi dall'uso accidentale. Entrambi questi metodi chiamano il metodo checkExit della classe SecurityManager . Quindi, per non consentire le operazioni di uscita e interruzione , un'applicazione può creare una politica di sicurezza utilizzando la classe SecurityManager e lanciare SecurityException dal metodo checkExit .

6. Conclusione

In questo tutorial, abbiamo esaminato i metodi System.exit () e Runtime.getRuntime (). Halt () con l'aiuto di un esempio. Inoltre, abbiamo anche parlato dell'utilizzo e delle migliori pratiche di questi metodi.

Come al solito, il codice sorgente completo di questo articolo è disponibile su Github.