9.11 Einen Abbruch der virtuellen Maschine erkennen
 
Läuft ein Java-Programm in der virtuellen Maschine, so kann der Benutzer jederzeit das Programm beenden, indem er die virtuelle Maschine beendet. Dies 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.
Ein Unix-System erzeugt Signale, die das Programm informieren, dass es beendet werden soll. Dies geschieht zum Beispiel, wenn der Benutzer das Programm mit der Tastenkombination (Strg)+(C) abbricht, das System herunterfährt oder der Benutzer sich vom System abmeldet. Ein Abbruchsignal ist beispielsweise SIGINT. Jedes Programm unter Unix kann diese Signale abfangen und darauf reagieren. Auf diese Weise lassen sich auch Programme schreiben, die dieses Abbruchsignal einfach ignorieren. Ein sauberes Programm kommt der Aufforderung nach, gibt Ressourcen frei und beendet sich.
Mit folgender Zeile starten wir den Thread t, wenn die JVM beendet wird und das Signal abgefangen werden kann. Die Formulierung ist extra vorsichtig, da unter Windows in einer Konsole zwar ähnlich wie unter Unix bei der Eingabe von (Strg)+(C) das Ende erkennbar ist, doch nicht, wenn mit dem Task-Manager der Prozess beendet wird. Unter Windows ist dies ein Aufruf von TerminateProcess. Unter Unix entspricht dem ein SIGKILL-Signal.
Thread t = ...
Runtime.getRuntime().addShutdownHook( t );
Zusätzlich zum Abbruch wird der Thread auch immer dann gestartet, wenn das Programm normal beendet wird. 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. Es können durchaus mehrere Threads unter dem Shutdown-Hook installiert sein. Wenn sich dann die JVM beendet, werden die Threads in beliebiger Reihenfolge abgearbeitet.
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 9.32
ThatsMyEnd.java
class ThatsMyEnd
{
public static void main( String[] args )
{
Runtime.getRuntime(). addShutdownHook ( new Thread()
{
@Override public void run()
{
System.out.println( "Hilfe! Man will mir an die Wäsche" );
}
} );
while ( true ) {
// Warten auf Abbruch auf der Kommandozeile
}
}
}
|
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. Rückgabewert ist true, falls der Hook registriert war und entfernt werden konnte. |
Um das Ende der virtuellen Maschine in den Versionen bis Java 1.3 zu erkennen, können wir für Unix die Bibliothek JavaSignals von Kevin Hester unter http://java-tutor.com/go/javasignals verwenden.
|