D) Code beim Beenden ausführen
Oft kommt es vor, dass etwas beim Beenden des eigenen Programms geschehen soll – z. B. um Einstellungen zu speichern oder eine Datenbankverbindung sauber zu trennen. Dieses Kapitel zeigt Ihnen, wie Sie etwas beim Beenden Ihres Programms automatisiert ausführen lassen können – ganz gleich wie Ihr Programm beendet wird. Hierzu verwenden wir die addShutdownHook
Objektmethode der Klasse Runtime
Ein kleines Beispiel
public class Test { public static void main(String[] args) { System.out.println("Programm start"); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { System.out.println("Das Programm wurde beendet"); } })); System.out.println("Es wird 5 Sekunden gewartet"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }
Zuerst holen wir uns über den statischen Aufruf getRuntime()
der Klasse java.lang.Runtime
das aktuelle Runtime-Objekt. Dort fügen wir dann einen initialisierten, aber noch nicht gestarteten, Thread via addShutdownHook
hinzu. Dieser Thread wird dann beim Beenden der Virtual Machine ausgeführt. Dies tritt in folgenden Fällen ein:
- Wenn das Programm normal beendet wurde, also der letzte Thread (ausgenommen Daemon-Threads) abgeschlossen, oder
System.exit
aufgerufen wurde. - Wenn der User die Beendigung des Programms durch bspw. Abbrechen des Vorgangs in der Konsole oder einem System-Ereignis (Herunterfahren des Rechners, Abmelden des Users, …) verursacht hat (terminieren der VM).
Sobald die Virtual Machine heruntergefahren wird, werden alle so registrierten Threads in einer zufälligen Reihenfolge zeitgleich gestartet. Alsbald die ShutdownHooks laufen, können diese nur noch über die Methode halt
unserer Runtime
Klasse gestoppt werden.
halt
terminiert die aktuelle JVM und sollte nur mit äußerster Vorsicht verwendet werden.
Auch ist es dann nicht mehr möglich neue ShutdownHooks hinzuzufügen oder bestehende zu entfernen. In solch einem Fall wird eine IllegalStateException
geworfen.
Richtlinien für ShutdownHooks:
- Thread-Safe
- Keine Deadlocks verursachen
- Sie sollten schnell beendet sein
Wichtig:
Es kann sehr selten dazu kommen, dass die Ausführung der JVM abgebrochen, also angehalten wird, ohne sauber heruntergefahren geworden zu sein. Dies tritt z. B. bei der Verwendung von „SIGKILL“ in Unix oder beim „TerminateProcess“-Aufruf unter Windows auf. Auch kann ein Fehler in einer nativen Bibliothek dies verursachen.
Tritt dieser worst-case ein, kann nicht garantiert werden, ob ein, mehrere, alle oder kein ShutdownHook ausgeführt wird.
Ein ganz ähnliches Problem löst das Beispiel, dass wir für Sie in unserem Wiki auf Byte-Welt bereit gestellt haben. In dem Beispiel zeigen wir Ihnen, wie man vor dem Schließen eines JFrames/JDialogs noch Code ausführen kann. Z.B. um dem Benutzer noch eine Frage zu stellen.
Hallo,
leider vermisse ich einen Versionsbezug! D.h. mit Java 1.4.2 ist der Code nicht ausführbar!
Grüße,
MK
Hallo MK,
wieso gehen Sie davon aus, dass der Code mit Java 1.4.2 nicht ausführbar ist? Die Methode
addShutdownHook
gibt es seit Java 1.3 und ansonsten finde ich nichts außergewöhnliches im Quellcode, das einer Kompatibilität mit Java 1.4.2 widersprechen würde.Grüße
Stefan