Java >> Java tutorial >  >> JVM

Tilføjelse af nedlukningskroge til JVM-applikationer

1. Oversigt

Det er typisk nemt at starte en service op. Men nogle gange skal vi have en plan for yndefuldt at lukke en ned.

I denne tutorial skal vi se på forskellige måder, hvorpå en JVM-applikation kan afsluttes. Derefter vil vi bruge Java API'er til at administrere JVM shutdown hooks. Se denne artikel for at få flere oplysninger om nedlukning af JVM i Java-applikationer.

2. JVM-nedlukning

JVM kan lukkes ned på to forskellige måder:

  1. En kontrolleret proces
  2. En brat måde

En kontrolleret proces lukker JVM'en ned, når enten:

  • Den sidste ikke-dæmon-tråd afsluttes. For eksempel, når hovedtråden afsluttes, starter JVM sin nedlukningsproces
  • Sender et afbrydelsessignal fra operativsystemet. For eksempel ved at trykke på Ctrl + C eller logge af OS
  • Ringer til System.exit()  fra Java-kode

Mens vi alle stræber efter yndefulde nedlukninger, kan JVM nogle gange lukke ned på en brat og uventet måde. JVM'en lukker brat ned, når :

  • Sender et dræbningssignal fra operativsystemet. For eksempel ved at udstede en kill -9
  • Ringer Runtime.getRuntime().halt()  fra Java-kode
  • Værts OS dør uventet, f.eks. ved strømsvigt eller OS panik

3. Nedlukningskroge

JVM tillader registreringsfunktioner at køre, før den afslutter sin lukning. Disse funktioner er normalt et godt sted at frigive ressourcer eller andre lignende husholdningsopgaver. I JVM-terminologi kaldes disse funktioner shutdown hooks .

Slukningskroge er grundlæggende initialiserede, men ustartede tråde . Når JVM begynder sin nedlukningsproces, vil den starte alle registrerede hooks i en uspecificeret rækkefølge. Efter at have kørt alle kroge, stopper JVM.

3.1. Tilføjelse af kroge

For at tilføje en shutdown-hook kan vi bruge Runtime.getRuntime().addShutdownHook()  metode:

Thread printingHook = new Thread(() -> System.out.println("In the middle of a shutdown"));
Runtime.getRuntime().addShutdownHook(printingHook);

Her udskriver vi blot noget til standard output, inden JVM lukker ned af sig selv. Hvis vi lukker JVM ned som følger:

> System.exit(129);
In the middle of a shutdown

Så vil vi se, at krogen faktisk udskriver beskeden til standard output.

JVM er ansvarlig for at starte krogtråde . Derfor, hvis den givne hook allerede er startet, vil Java give en undtagelse:

Thread longRunningHook = new Thread(() -> {
    try {
        Thread.sleep(300);
    } catch (InterruptedException ignored) {}
});
longRunningHook.start();

assertThatThrownBy(() -> Runtime.getRuntime().addShutdownHook(longRunningHook))
  .isInstanceOf(IllegalArgumentException.class)
  .hasMessage("Hook already running");

Vi kan naturligvis heller ikke registrere en hook flere gange:

Thread unfortunateHook = new Thread(() -> {});
Runtime.getRuntime().addShutdownHook(unfortunateHook);

assertThatThrownBy(() -> Runtime.getRuntime().addShutdownHook(unfortunateHook))
  .isInstanceOf(IllegalArgumentException.class)
  .hasMessage("Hook previously registered");

3.2. Fjernelse af kroge

Java giver en tvilling fjern  metode til at fjerne en bestemt shutdown-hook efter registrering:

Thread willNotRun = new Thread(() -> System.out.println("Won't run!"));
Runtime.getRuntime().addShutdownHook(willNotRun);

assertThat(Runtime.getRuntime().removeShutdownHook(willNotRun)).isTrue();

removeShutdownHook() metode returnerer true  når nedlukningskrogen er fjernet.

3.3. Forbehold

JVM'en kører kun shutdown hooks i tilfælde af normale opsigelser. Så når en ekstern kraft dræber JVM-processen brat, får JVM'en ikke en chance for at udføre shutdown-hooks. Derudover vil stop af JVM fra Java-kode også have den samme effekt:

Thread haltedHook = new Thread(() -> System.out.println("Halted abruptly"));
Runtime.getRuntime().addShutdownHook(haltedHook);
        
Runtime.getRuntime().halt(129);

stoppet metode med magt afslutter den aktuelt kørende JVM. Derfor vil registrerede nedlukningskroge ikke få en chance for at udføre.

4. Konklusion

I denne tutorial har vi set på forskellige måder, hvorpå en JVM-applikation muligvis kan afsluttes. Derefter brugte vi et par runtime API'er til at registrere og afregistrere shutdown hooks.

Som sædvanlig er prøvekoden tilgængelig på GitHub.


Java tag