Legge til Shutdown Hooks for JVM Applications
1. Oversikt
Det er vanligvis enkelt å starte en tjeneste. Imidlertid trenger vi noen ganger å ha en plan for å stenge en elegant.
I denne veiledningen skal vi se på forskjellige måter en JVM-applikasjon kan avslutte. Deretter bruker vi Java APIer til å administrere JVM-avstengningskroker. Se denne artikkelen for å lære mer om å slå av JVM i Java-applikasjoner.
2. JVM Shutdown
JVM kan stenges på to forskjellige måter:
- En kontrollert prosess
- En brå måte
En kontrollert prosess slår av JVM når enten:
- Den siste ikke-demon-tråden avsluttes. For eksempel når hovedtråden går ut, starter JVM avstengingsprosessen
- Sende et avbruddssignal fra operativsystemet. For eksempel ved å trykke Ctrl + C eller logge av operativsystemet
- Ringer System.exit () fra Java-kode
Mens vi alle strever for elegante nedleggelser, kan JVM noen ganger slå seg av på en brå og uventet måte. JVM slår seg brått ned når:
- Sende et drapssignal fra operativsystemet. For eksempel ved å utstede en drepe -9
- Ringer Runtime.getRuntime (). Stopp () fra Java-kode
- Vertens operativsystem dør uventet, for eksempel i strømbrudd eller OS-panikk
3. Stengekroker
JVM tillater at registreringsfunksjoner kjøres før den avsluttes. Disse funksjonene er vanligvis et godt sted for å frigjøre ressurser eller andre lignende husholdningsoppgaver. I JVM-terminologi, disse funksjonene kalles shutdown kroker.
Stengekroker er i utgangspunktet initialiserte, men ikke startede tråder. Når JVM begynner avstengingsprosessen, vil den starte alle registrerte kroker i en uspesifisert rekkefølge. Etter å ha kjørt alle kroker, stopper JVM.
3.1. Legge til kroker
For å legge til en stengekrok, kan vi bruke Runtime.getRuntime (). AddShutdownHook () metode:
Tråd printingHook = ny tråd (() -> System.out.println ("Midt i en avstengning")); Runtime.getRuntime (). AddShutdownHook (printingHook);
Her skriver vi ganske enkelt ut noe til standardutgangen før JVM slår seg av. Hvis vi stenger JVM slik:
> System.exit (129); Midt i en nedleggelse
Så får vi se at kroken faktisk skriver ut meldingen til standard utgang.
JVM er ansvarlig for å starte kroktråder. Derfor, hvis den gitte kroken allerede er startet, vil Java kaste et unntak:
Tråd longRunningHook = ny tråd (() -> {prøv {Thread.sleep (300);} fangst (InterruptedException ignorert) {}}); longRunningHook.start (); assertThatThrownBy (() -> Runtime.getRuntime (). addShutdownHook (longRunningHook)) .isInstanceOf (IllegalArgumentException.class) .hasMessage ("Hook allerede kjører");
Selvfølgelig kan vi heller ikke registrere en krok flere ganger:
Tråd unfortunateHook = ny tråd (() -> {}); Runtime.getRuntime (). AddShutdownHook (unfortunateHook); assertThatThrownBy (() -> Runtime.getRuntime (). addShutdownHook (unfortunateHook)) .isInstanceOf (IllegalArgumentException.class) .hasMessage ("Hook tidligere registrert");
3.2. Fjerne kroker
Java gir en tvilling fjerne metode for å fjerne en bestemt stengekrok etter registrering:
Tråden willNotRun = ny tråd (() -> System.out.println ("Vil ikke kjøre!")); Runtime.getRuntime (). AddShutdownHook (willNotRun); assertThat (Runtime.getRuntime (). removeShutdownHook (willNotRun)). isTrue ();
De removeShutdownHook () metoden returnerer ekte når lukkekroken er fjernet.
3.3. Advarsler
JVM kjører bare stengekroker i tilfelle normale avslutninger. Så når en ekstern styrke dreper JVM-prosessen brått, vil ikke JVM få sjansen til å utføre stengekroker. I tillegg vil stopp av JVM fra Java-kode også ha samme effekt:
Tråd haltedHook = ny tråd (() -> System.out.println ("Stanset brått")); Runtime.getRuntime (). AddShutdownHook (haltedHook); Runtime.getRuntime (). Stopp (129);
De stopp metoden terminerer nåværende JVM med makt. Derfor vil registrerte stengekroker ikke få sjansen til å utføre.
4. Konklusjon
I denne opplæringen så vi på forskjellige måter en JVM-applikasjon muligens kan avslutte. Deretter brukte vi noen API-er for runtime for å registrere og avregistrere stengekroker.
Eksempelkoden er som vanlig tilgjengelig på GitHub.