3.13Einen Abbruch der virtuellen Maschine erkennen
3.13.1Shutdown-Hook
Läuft ein Java-Programm, so kann der Benutzer es jederzeit beenden, indem er die virtuelle Maschine stoppt. Das kann er zum Beispiel durch die Tastenkombination (Strg) + (C) auf der Konsole oder auch durch Abbruchsignale vornehmen. Ein plötzlicher Programmabbruch kann aber für das Programm sehr unsicher sein, und zwar aus den gleichen Gründen wie bei einem unvermittelten Abbruch durch die stop()-Methode der Klasse Thread. Daher bietet Java durch einen Shutdown-Hook die Möglichkeit, das Abbruchsignal zu erkennen und Ressourcen sauber freizugeben. Das Teilwort Hook erinnert an einen Haken, der sich ins System einhängt, um Informationen abzugreifen. Der Hook ist ein initialisierter, aber noch nicht gestarteter Thread.
[zB]Beispiel
Eine Endlosschleife schmort im eigenen Saft. Der eingefügte Hook reagiert auf das Ende der virtuellen Maschine. Das Programm muss auf der Konsole beendet werden, da die meisten Entwicklungsumgebungen das (Strg) + (C) nicht an die Java-Umgebung weiterleiten.
Listing 3.50com/tutego/insel/thread/ThatsMyEnd.java, main()
@Override public void run() {
System.out.println( "Jedes Leben endet tödlich." );
}
} );
JOptionPane.showConfirmDialog( null, "Ende?" );
System.exit( 0 );
Zusätzlich zum bewussten Abbruch wird der Thread auch immer dann ausgeführt, wenn das Programm normal beendet wird. Es können mehrere Threads als Shutdown-Hooks installiert sein. Wenn sich dann die JVM beendet, werden die Threads in beliebiger Reihenfolge abgearbeitet.
[»]Hinweis
Wird unter Windows der Prozess mit dem Task-Manager beendet, läuft der Shutdown-Hook nicht!
void addShutdownHook(Thread hook)
Startet den angegebenen Thread, wenn die JVM beendet wird. Der Thread kann keinen neuen Thread unter dem Hook registrieren. Die run()-Methode des Threads sollte schnell ablaufen, um das Beenden der JVM nicht länger als nötig aufzuhalten. Es ist nicht möglich (vorgesehen), das bevorstehende Ende der JVM zu verhindern.boolean removeShutdownHook(Thread hook)
Entfernt den angegebenen Hook. Der Rückgabewert ist true, falls der Hook registriert war und entfernt werden konnte.
3.13.2Signale
Das Betriebssystem sendet beim Abbruch eines Programms Signale. Für Windows-/Unix-Systeme sind das zum Beispiel INT (Abbruch zum Beispiel mit (Strg) + (C)), TERM (Aufforderung zur Terminierung), BREAK (Break-Anforderung vom Termin) usw.
Java kann diese unterschiedlichen Feinheiten des Programmabbruchs nicht auswerten, jedenfalls nicht mit einer erlaubten API. Es gibt aber zwei Klassen, sun.misc.Signal und sun.misc.SignalHandler, die verwendet werden können, wenn Entwickler sich der Konsequenzen bewusst sind, dass diese API in Zukunft verschwinden könnte. Die Nutzung sieht so aus:
public void handle( Signal signal ) { … }
}
String signalName = "TERM";
handler = Signal.handle( new Signal( signalName ), new MySignalHandler() );
Weitere Informationen auch zu den unterschiedlichen Signaltypen liefern http://tutego.de/go/signal und die referenzierten Unterseiten.