Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren für die Java 2-Plattform in der Version 5
Java ist auch eine Insel

Java ist auch eine Insel
5., akt. und erw. Auflage
1454 S., mit CD, 49,90 Euro
Galileo Computing
ISBN 3-89842-747-1
gp Kapitel 9 Threads und nebenläufige Programmierung
  gp 9.1 Prozesse und Threads
    gp 9.1.1 Wie parallele Programme die Geschwindigkeit steigern können
  gp 9.2 Threads erzeugen
    gp 9.2.1 Threads über die Schnittstelle Runnable implementieren
    gp 9.2.2 Thread mit Runnable starten
    gp 9.2.3 Der Name eines Threads
    gp 9.2.4 Die Klasse Thread erweitern
    gp 9.2.5 Wer bin ich?
  gp 9.3 Der Ausführer (Executor) kommt
    gp 9.3.1 Die Schnittstelle Executor
    gp 9.3.2 Die Thread-Pools
    gp 9.3.3 Threads mit Rückgabe über Callable
    gp 9.3.4 Mehrere Callable abarbeiten
    gp 9.3.5 Mit ScheduledExecutorService wiederholende Ausgaben und Zeitsteuerungen
  gp 9.4 Die Zustände eines Threads
    gp 9.4.1 Threads schlafen
    gp 9.4.2 Das Ende eines Threads
    gp 9.4.3 UncaughtExceptionHandler für unbehandelte Ausnahmen
    gp 9.4.4 Einen Thread höflich mit Interrupt beenden
    gp 9.4.5 Der stop() von außen und die Rettung mit ThreadDeath
    gp 9.4.6 Ein Rendezvous mit join() und Barrier sowie Austausch mit Exchanger
    gp 9.4.7 Mit yield() auf Rechenzeit verzichten
    gp 9.4.8 Arbeit niederlegen und wieder aufnehmen
    gp 9.4.9 Priorität
    gp 9.4.10 Der Thread ist ein Dämon
  gp 9.5 Synchronisation über kritische Abschnitte
    gp 9.5.1 Gemeinsam genutzte Daten
    gp 9.5.2 Probleme beim gemeinsamen Zugriff und kritische Abschnitte
    gp 9.5.3 Punkte parallel initialisieren
    gp 9.5.4 i++ sieht atomar aus, ist es aber nicht
    gp 9.5.5 Kritische Abschnitte schützen
    gp 9.5.6 Schützen mit ReentrantLock
    gp 9.5.7 Synchronisieren mit synchronized
    gp 9.5.8 Synchronized-Methoden der Klasse StringBuffer
    gp 9.5.9 Mit synchronized synchronisierte Blöcke
    gp 9.5.10 Look-Freigabe im Fall von Exceptions
    gp 9.5.11 Mit synchronized nachträglich synchronisieren
    gp 9.5.12 Monitore sind reentrant, gut für die Geschwindigkeit
    gp 9.5.13 Synchronisierte Methodenaufrufe zusammenfassen
    gp 9.5.14 Deadlocks
    gp 9.5.15 Erkennen von Deadlocks
  gp 9.6 Synchronisation über Warten und Benachrichtigen
    gp 9.6.1 Die Schnittstelle Condition
    gp 9.6.2 Beispiel Erzeuger-Verbraucher-Programm
    gp 9.6.3 Warten mit wait() und Aufwecken mit notify()
    gp 9.6.4 Falls der Lock fehlt: IllegalMonitorStateException
    gp 9.6.5 Semaphoren
  gp 9.7 Atomares und frische Werte mit volatile
    gp 9.7.1 Der Modifizierer volatile bei Objekt-/Klassenvariablen
    gp 9.7.2 Das Paket java.util.concurrent.atomic
  gp 9.8 Mit dem Thread verbundene Variablen
    gp 9.8.1 ThreadLocal
    gp 9.8.2 InheritableThreadLocal
  gp 9.9 Gruppen von Threads in einer Thread-Gruppe
    gp 9.9.1 Aktive Threads in der Umgebung
    gp 9.9.2 Etwas über die aktuelle Thread-Gruppe herausfinden
    gp 9.9.3 Threads in einer Thread-Gruppe anlegen
    gp 9.9.4 Methoden von Thread und ThreadGroup im Vergleich
  gp 9.10 Die Klassen Timer und TimerTask
    gp 9.10.1 Job-Scheduler Quartz
  gp 9.11 Einen Abbruch der virtuellen Maschine erkennen


Galileo Computing

9.11 Einen Abbruch der virtuellen Maschine erkennetoptop

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
    }
  }
}

class java.lang.  Runtime  

gp  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.
gp  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.

 << zurück




Copyright © Galileo Press GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de