Tilføjelse af lukkekroge til JVM-applikationer

1. Oversigt

Det er typisk let at starte en tjeneste. Imidlertid er vi undertiden nødt til at have en plan for at lukke en behageligt ned.

I denne vejledning skal vi se på forskellige måder, en JVM-applikation kan afslutte. Derefter bruger vi Java API'er til at styre JVM-lukningskroge. Se denne artikel for at lære mere 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 ned, når enten:

  • Den sidste ikke-dæmonstråd afsluttes. For eksempel, når hovedtråden afsluttes, starter JVM sin nedlukningsproces
  • Afsendelse af et afbrydesignal fra operativsystemet. For eksempel ved at trykke på Ctrl + C eller logge af OS
  • Ringer 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 lukker brat ned, når:

  • Afsendelse af et dræbningssignal fra operativsystemet. For eksempel ved at udstede en dræb -9
  • Ringer Runtime.getRuntime (). Stop () fra Java-kode
  • Værts-OS dør uventet, for eksempel i strømsvigt eller OS-panik

3. Lukkekroge

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

Lukningskrog er grundlæggende initialiserede, men ikke startede tråde. Når JVM begynder sin nedlukningsproces, starter den alle registrerede kroge 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 nedlukningskrog kan vi bruge Runtime.getRuntime (). AddShutdownHook () metode:

TrådprintHook = ny tråd (() -> System.out.println ("Midt i en nedlukning")); Runtime.getRuntime (). AddShutdownHook (printingHook);

Her udskriver vi simpelthen noget til standardoutputtet, før JVM lukker sig selv ned. Hvis vi lukker JVM som følger:

> System.exit (129); Midt i en nedlukning

Så ser vi, at krogen faktisk udskriver beskeden til standardoutput.

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

Tråd longRunningHook = ny tråd (() -> {prøv {Thread.sleep (300);} fang (InterruptedException ignoreret) {}}); longRunningHook.start (); assertThatThrownBy (() -> Runtime.getRuntime (). addShutdownHook (longRunningHook)) .isInstanceOf (IllegalArgumentException.class) .hasMessage ("Krog kører allerede"); 

Vi kan naturligvis heller ikke registrere en krog flere gange:

Tråd unfortunateHook = ny tråd (() -> {}); Runtime.getRuntime (). AddShutdownHook (unfortunateHook); assertThatThrownBy (() -> Runtime.getRuntime (). addShutdownHook (unfortunateHook)) .isInstanceOf (IllegalArgumentException.class) .hasMessage ("Hook tidligere registreret");

3.2. Fjernelse af kroge

Java giver en tvilling fjerne metode til at fjerne en bestemt lukningskrog efter registrering af den:

Tråd willNotRun = ny tråd (() -> System.out.println ("Kører ikke!")); Runtime.getRuntime (). AddShutdownHook (willNotRun); assertThat (Runtime.getRuntime (). removeShutdownHook (willNotRun)). isTrue (); 

Det removeShutdownHook () metoden vender tilbage rigtigt når lukkekrogen er fjernet med succes.

3.3. Advarsler

JVM kører kun lukkekroge i tilfælde af normale afslutninger. Så når en ekstern kraft dræber JVM-processen pludseligt, får JVM ikke en chance for at udføre nedlukningskrog. Derudover har stop af JVM fra Java-kode også den samme effekt:

Tråd haltedHook = ny tråd (() -> System.out.println ("Halt brat")); Runtime.getRuntime (). AddShutdownHook (haltedHook); Runtime.getRuntime (). Stop (129); 

Det standse metoden med magt afslutter den aktuelt kørende JVM. Derfor vil registrerede lukningskroge ikke få en chance for at udføre.

4. Konklusion

I denne vejledning så vi på forskellige måder, en JVM-applikation muligvis kan afslutte. Derefter brugte vi et par runtime-API'er til at registrere og afregistrere lukningskroge.

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