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

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Generics, innere Klassen
10 Die Klassenbibliothek
11 Threads und nebenläufige Programmierung
12 Datenstrukturen und Algorithmen
13 Raum und Zeit
14 Dateien und Datenströme
15 Die eXtensible Markup Language (XML)
16 Grafische Oberflächen mit Swing
17 Grafikprogrammierung
18 Netzwerkprogrammierung
19 Verteilte Programmierung mit RMI und Web–Services
20 JavaServer Pages und Servlets
21 Applets
22 Midlets und die Java ME
23 Datenbankmanagement mit JDBC
24 Reflection und Annotationen
25 Logging und Monitoring
26 Sicherheitskonzepte
27 Java Native Interface (JNI)
28 Dienstprogramme für die Java-Umgebung
Stichwort

Download:
- ZIP, ca. 14,1 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel (8. Auflage) von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel (8. Auflage)

Java ist auch eine Insel (8. Aufl.)
8., aktual. Auflage, geb., mit DVD
1.475 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1371-4
Pfeil 11 Threads und nebenläufige Programmierung
Pfeil 11.1 Nebenläufigkeit
Pfeil 11.1.1 Threads und Prozesse
Pfeil 11.1.2 Wie parallele Programme die Geschwindigkeit steigern können
Pfeil 11.1.3 Was Java für Nebenläufigkeit alles bietet
Pfeil 11.2 Threads erzeugen
Pfeil 11.2.1 Threads über die Schnittstelle Runnable implementieren
Pfeil 11.2.2 Thread mit Runnable starten
Pfeil 11.2.3 Der Name eines Threads
Pfeil 11.2.4 Die Klasse Thread erweitern
Pfeil 11.2.5 Wer bin ich?
Pfeil 11.3 Die Zustände eines Threads
Pfeil 11.3.1 Threads schlafen
Pfeil 11.3.2 Mit yield() auf Rechenzeit verzichten
Pfeil 11.3.3 Das Ende eines Threads
Pfeil 11.3.4 UncaughtExceptionHandler für unbehandelte Ausnahmen
Pfeil 11.3.5 Einen Thread höflich mit Interrupt beenden
Pfeil 11.3.6 Der stop() von außen und die Rettung mit ThreadDeath
Pfeil 11.3.7 Ein Rendezvous mit join()
Pfeil 11.3.8 Barrier und Austausch mit Exchanger
Pfeil 11.3.9 Arbeit niederlegen und wieder aufnehmen
Pfeil 11.3.10 Priorität
Pfeil 11.3.11 Der Thread als Dämon
Pfeil 11.4 Der Ausführer (Executor) kommt
Pfeil 11.4.1 Die Schnittstelle Executor
Pfeil 11.4.2 Die Thread-Pools
Pfeil 11.4.3 Threads mit Rückgabe über Callable
Pfeil 11.4.4 Mehrere Callable abarbeiten
Pfeil 11.4.5 Mit ScheduledExecutorService wiederholende Ausgaben und Zeitsteuerungen
Pfeil 11.5 Synchronisation über kritische Abschnitte
Pfeil 11.5.1 Gemeinsam genutzte Daten
Pfeil 11.5.2 Probleme beim gemeinsamen Zugriff und kritische Abschnitte
Pfeil 11.5.3 Punkte parallel initialisieren
Pfeil 11.5.4 i++ sieht atomar aus, ist es aber nicht
Pfeil 11.5.5 Kritische Abschnitte schützen
Pfeil 11.5.6 Schützen mit ReentrantLock
Pfeil 11.5.7 Synchronisieren mit synchronized
Pfeil 11.5.8 Synchronized-Methoden der Klasse StringBuffer
Pfeil 11.5.9 Mit synchronized synchronisierte Blöcke
Pfeil 11.5.10 Dann machen wir doch gleich alles synchronisiert!
Pfeil 11.5.11 Lock-Freigabe im Fall von Exceptions
Pfeil 11.5.12 Mit synchronized nachträglich synchronisieren
Pfeil 11.5.13 Monitore sind reentrant – gut für die Geschwindigkeit
Pfeil 11.5.14 Synchronisierte Methodenaufrufe zusammenfassen
Pfeil 11.5.15 Deadlocks
Pfeil 11.6 Synchronisation über Warten und Benachrichtigen
Pfeil 11.6.1 Die Schnittstelle Condition
Pfeil 11.6.2 It’s Disco-Time
Pfeil 11.6.3 Warten mit wait() und Aufwecken mit notify()
Pfeil 11.6.4 Falls der Lock fehlt: IllegalMonitorStateException
Pfeil 11.6.5 Semaphor
Pfeil 11.7 Atomare Operationen und frische Werte mit volatile
Pfeil 11.7.1 Der Modifizierer volatile bei Objekt-/Klassenvariablen
Pfeil 11.7.2 Das Paket java.util.concurrent.atomic
Pfeil 11.8 Mit dem Thread verbundene Variablen
Pfeil 11.8.1 ThreadLocal
Pfeil 11.8.2 InheritableThreadLocal
Pfeil 11.9 Gruppen von Threads in einer Thread-Gruppe
Pfeil 11.9.1 Aktive Threads in der Umgebung
Pfeil 11.9.2 Etwas über die aktuelle Thread-Gruppe herausfinden
Pfeil 11.9.3 Threads in einer Thread-Gruppe anlegen
Pfeil 11.9.4 Methoden von Thread und ThreadGroup im Vergleich
Pfeil 11.10 Zeitgesteuerte Abläufe
Pfeil 11.10.1 Die Klassen Timer und TimerTask
Pfeil 11.10.2 Job-Scheduler Quartz
Pfeil 11.11 Einen Abbruch der virtuellen Maschine erkennen
Pfeil 11.12 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

11.9 Gruppen von Threads in einer Thread-Gruppe Zur nächsten ÜberschriftZur vorigen Überschrift

Wenn wir einen Thread erzeugen, gehört dieser automatisch zu einer Gruppe, die durch ein ThreadGroup-Objekt repräsentiert wird. Die Verwaltung ist Aufgabe der Laufzeitumgebung. Die Gruppenzugehörigkeit bekommt jeder Thread bei seiner Erzeugung zugeteilt; wir können sie beeinflussen. Entweder geben wir die Gruppe explizit an, wofür es einen passenden Konstruktor gibt, oder der Thread wird automatisch der Gruppe jenes Threads zugeordnet, der ihn erzeugt hat. Da Thread-Gruppen baumartig organisiert sind, kann jede Thread-Gruppe wiederum weitere Untergruppen besitzen. Die Wurzel dieses Baums bildet für Benutzer-Threads die Gruppe main. Über diese Gruppenzugehörigkeit lassen sich Threads leicht verwalten, da sich beispielsweise alle Threads einer Gruppe gleichzeitig stoppen lassen oder die Priorität geändert werden kann. Von Applets erzeugte Threads gehören automatisch zu speziellen Untergruppen, sodass sie die Laufzeitumgebung nicht negativ beeinflussen.


Galileo Computing - Zum Seitenanfang

11.9.1 Aktive Threads in der Umgebung Zur nächsten ÜberschriftZur vorigen Überschrift

Es gibt zwei Möglichkeiten herauszufinden, welche Threads gerade im System laufen. Der erste Weg führt über die Klasse Thread, der zweite über die Klasse ThreadGroup.


class java.lang.Thread 
implements Runnable

  • static int activeCount()
    Liefert die Anzahl der noch nicht beendeten Threads in der Gruppe des aktiven Threads.
  • static int enumerate( Thread[] tarray )
    Jeder Thread in der gleichen Gruppe wie der aktive Thread und alle Threads in den Untergruppen dieser Gruppe werden in das Feld kopiert. Der SecurityManager überprüft, ob wir dies überhaupt dürfen, und kann eine SecurityException auslösen. Die Rückgabe ist die Anzahl kopierter Elemente im Feld.

Galileo Computing - Zum Seitenanfang

11.9.2 Etwas über die aktuelle Thread-Gruppe herausfinden Zur nächsten ÜberschriftZur vorigen Überschrift

Das folgende Programm nutzt die Methode getThreadGroup(), um das ThreadGroup-Objekt des aktuellen Threads zu bekommen. Anschließend verwendet es getParent(), um die Thread-Gruppen ebenenweise nach oben zu durchlaufen und somit das Vater-Objekt für alle Threads auszulesen.

Listing 11.31 com/tutego/insel/thread/group/ShowThreadsInMain.java

package com.tutego.insel.thread.group; 
 
public class ShowThreadsInMain 
{ 
  public static void main( String[] args ) 
  { 
    ThreadGroup top = Thread.currentThread().getThreadGroup(); 
 
    while ( top.getParent() != null ) 
      top = top.getParent(); 
 
    showGroupInfo( "  ", top ); 
  } 
 
  public static void showGroupInfo( String indent, ThreadGroup group ) 
  { 
    Thread[] threads = new Thread[ group.activeCount() ]; 
    group.enumerate( threads, false ); 
    System.out.println( group ); 
 
    for ( Thread t : threads ) 
      if ( t != null ) 
        System.out.printf( "%s%s -> %s ist %sDaemon-Thread%n", 
                           indent, group.getName(), t, t.isDaemon() ? "" : "kein " ); 
 
    ThreadGroup[] activeGroup = new ThreadGroup[ group.activeGroupCount() ]; 
    group.enumerate( activeGroup, false ); 
 
    for ( ThreadGroup g : activeGroup ) 
      showGroupInfo( indent + indent, g ); 
  } 
}

Dann wird mit der schon bekannten enumerate()-Methode eine Liste erstellt und eine Auflistung aller Untergruppen auf den Bildschirm ausgegeben. Die Anzahl der Threads in der Gruppe ergibt sich mit activeCount(). Die Methoden enumerate() sowie activeCount() beziehen sich hier auf Objektmethoden einer Thread-Gruppe und nicht mehr auf Klassenmethoden von Thread.

java.lang.ThreadGroup[name=system,maxpri=10] 
  system -> Thread[Reference Handler,10,system] is Daemon 
  system -> Thread[Finalizer,8,system] is Daemon 
  system -> Thread[Signal Dispatcher,9,system] is Daemon 
  system -> Thread[Attach Listener,5,system] is Daemon 
java.lang.ThreadGroup[name=main,maxpri=10] 
    main -> Thread[main,5,main] is no Daemon

class java.lang.Thread 
implements Runnable

  • static Thread currentThread()
    Liefert eine Referenz auf den aktuell laufenden Thread.
  • final ThreadGroup getThreadGroup()
    Liefert die Thread-Gruppe, zu der der Thread gehört. Wenn es den Thread schon nicht mehr gibt, liefert die Methode null.

class java.lang.ThreadGroup 
implements Thread.UncaughtExceptionHandler

  • final ThreadGroup getParent()
    Liefert die Obergruppe der Thread-Gruppe.
  • int activeCount()
    Liefert die Anzahl aktiver Threads in der Gruppe inklusive aller Untergruppen.
  • int activeGroupCount()
    Liefert die Anzahl aktiver Untergruppen in der Gruppe.
  • int enumerate( Thread[] threadList )
    Kopiert eine Referenz auf jeden aktiven Thread der Gruppe und auf alle Threads in ihren Untergruppen in das Array.
  • int enumerate( Thread[] threadList, boolean recurse )
    Kopiert eine Referenz auf jeden aktiven Thread der Gruppe in das Array. Ist recurse gleich true, werden auch Referenzen auf die Threads der Untergruppen mit kopiert.
  • int enumerate( ThreadGroup[] groupList )
    Kopiert Referenzen auf die Untergruppen, die mindestens einen aktiven Thread enthalten, inklusive aller Unteruntergruppen in das Array.
  • int enumerate( ThreadGroup[] groupList, boolean recurse )
    Kopiert Referenzen auf jede aktive Untergruppe inklusive aller Unteruntergruppen, wenn recurse gleich true ist.

Ein Array der passenden Größe müssen wir zunächst anlegen. Dies geschieht am besten mit activeCount(). Ist das Array für die Threads zu klein, werden die überzähligen Threads nicht mehr in das Array kopiert.


Galileo Computing - Zum Seitenanfang

11.9.3 Threads in einer Thread-Gruppe anlegen Zur nächsten ÜberschriftZur vorigen Überschrift

Wollen wir Threads in einer Gruppe anlegen, dann müssen wir zunächst ein ThreadGroup-Objekt erzeugen. Dazu bietet die Klasse zwei Konstruktoren. Im ersten müssen wir lediglich den Namen der Gruppe angeben. Da eine Thread-Gruppe, die mehrere Threads zusammenfasst, wiederum Mitglied eines ThreadGroup-Objekts sein kann, existiert ein zweiter Konstruktor, der die übergeordnete Gruppe bestimmt. Ohne diese Angabe wird die Thread-Gruppe des aktuellen Threads zum Vater der neuen Gruppe.


class java.lang.ThreadGroup 
implements Thread.UncaughtExceptionHandler

  • ThreadGroup( String name )
    Erzeugt eine Thread-Gruppe namens name.
  • ThreadGroup( ThreadGroup parent, String name )
    Erzeugt eine neue Thread-Gruppe, deren Vater parent ist.

Die Gruppe haben wir angelegt, nun fehlen uns noch die Threads. Diese können nur bei ihrer Erzeugung in die Gruppe aufgenommen werden. Dafür bietet uns die Thread-Klasse spezielle Konstruktoren, um den neuen Thread einer bestimmten Gruppe hinzuzufügen. Folgende Zeilen reichen aus, um die drei Comic-Helden in eine Gruppe zu stecken:

ThreadGroup group = new ThreadGroup( "Disney Family" ); 
Thread thread1    = new Thread( group, "Donald" ); 
Thread thread2    = new Thread( group, "Daisy" ); 
Thread thread2    = new Thread( group, "Micky" );

Hinweis Die Zugehörigkeit eines Threads zu einer Gruppe lässt sich nachträglich nicht mehr ändern.



class java.lang.Thread 
implements Runnable

  • Thread( ThreadGroup group, Runnable target, String name )
    Erzeugt ein neues Thread-Objekt mit dem Namen name in der Gruppe group und dem Runnable-Objekt target, das die auszuführende run()-Methode enthält. Ist die Gruppe null, so wird der Thread in der Gruppe erzeugt, in der auch der erzeugende Thread liegt. Ist target gleich null, hat das Thread-Objekt selbst das passende run().
  • Thread( ThreadGroup group, Runnable target )
    Erzeugt ein neues Thread-Objekt. Der Konstruktor verweist auf Thread(parent, target, "Thread-" + n), wobei n eine Ganzzahl ist, die mit nextThreadNum() erfragt wird. Bei jedem erzeugten Thread wird n inkrementiert.
  • Thread( ThreadGroup group, String name )
    Erzeugt ein neues Thread-Objekt in der Gruppe group. Entspricht dem Konstruktor Thread(group, null, name).

Das nachfolgende Beispiel zeigt die Erstellung und Nutzung einer eigenen Thread-Gruppe.

Listing 11.32 com/tutego/insel/thread/group/ThreadInThreadGroup.java

package com.tutego.insel.thread.group; 
 
public class ThreadInThreadGroup 
{ 
  static public void main( String[] args ) 
  { 
    ThreadGroup group = new ThreadGroup( "Helden" ); 
 
    new OwnThread( group, "Darkwing Duck" ).start(); 
    new OwnThread( group, "Kikky" ).start(); 
 
    Thread[] threadArray = new Thread[ group.activeCount() ]; 
 
    // Fill array with all Threads of the group 
 
    group.enumerate( threadArray ); 
 
    // List array 
 
    for ( Thread t : threadArray ) 
      System.out.println( t ); 
 
    System.out.println( "--" ); 
 
    group.list(); 
  } 
} 
 
class OwnThread extends Thread 
{ 
  public OwnThread( ThreadGroup group, String name ) { 
    super( group, name ); 
  } 
 
  @Override public void run() 
  { 
    for ( int i = 0; i < 3; i++ ) 
    { 
      System.out.println( getName() + ": Ich bin der Schrecken, "+ 
                          "der die Nacht durchflattert" ); 
    } 
  } 
}

Läuft das Programm, produziert es eine Ausgabe folgender Art:

Darkwing Duck: Ich bin der Schrecken, der die Nacht durchflattert 
Darkwing Duck: Ich bin der Schrecken, der die Nacht durchflattert 
Darkwing Duck: Ich bin der Schrecken, der die Nacht durchflattert 
Kikky: Ich bin der Schrecken, der die Nacht durchflattert 
Kikky: Ich bin der Schrecken, der die Nacht durchflattert 
Kikky: Ich bin der Schrecken, der die Nacht durchflattert 
Thread[Darkwing Duck,5,Helden] 
 
Thread[Kikky,5,] 
-- 
java.lang.ThreadGroup[name=Helden,maxpri=10]

Wesentlich einfacher ist die Testausgabe einer Thread-Gruppe mit der Objektmethode list(). Diese Methode ergibt aber nur zu Testzwecken Sinn.


class java.lang.ThreadGroup 
implements Thread.UncaughtExceptionHandler

  • void list()
    Schreibt eine Liste mit Informationen über die Thread-Gruppe auf die Standardausgabe.

Galileo Computing - Zum Seitenanfang

11.9.4 Methoden von Thread und ThreadGroup im Vergleich topZur vorigen Überschrift

Einige Methoden, die ein Thread besitzt, lassen sich auf Gruppen übertragen, wobei es zum Teil Bedeutungsunterschiede gibt. So suggeriert vielleicht setMaxPriority(), dass die Prio-rität aller Threads in der Gruppe verändert wird, aber das ist nicht so. setMaxPriority() und getMaxPriority() beziehen sich auf die interne Variable maxPriority aus der Thread-Gruppe – die Threads aus der Gruppe werden von den beiden Methoden überhaupt nicht beeinflusst.


class java.lang.ThreadGroup 
implements Thread.UncaughtExceptionHandler

  • final void setMaxPriority( int priority )
    Setzt die höchstens einstellbare Priorität für Threads aus der ThreadGroup. Zum Beispiel: Hat ein Thread die Priorität 7 und wird danach maxPriority seiner Gruppe auf 3 gesetzt, dann wird die Priorität des Threads bei einem folgenden setPriority(i) (wobei i zwischen 3 und 7 sein kann) auch nur auf 3 gesetzt. Existierende Threads ändern ihre Priorität nicht.
  • final int getMaxPriority()
    Gibt zurück, wie hoch die Priorität eines Threads aus einer ThreadGroup höchstens gesetzt werden kann. Sie gibt nicht zurück, wie hoch die höchste Priorität aller Prioritäten der Threads aus der Thread-Gruppe ist!

Hinweis Wird von einem Thread ein neuer Thread erzeugt, erbt der neue Thread üblicherweise die Priorität. Ist die Priorität des erzeugenden Threads aber höher als die maximale Priorität der Gruppe, dann erhält der neue Thread trotzdem nur den maximalen Prioritätswert der Gruppe zuerkannt.


Veraltete Methoden und Ähnliches

Einige Methoden sind veraltet und sollten nicht mehr verwendet werden. Dazu zählen allowThreadSuspension(boolean), resume(), stop() und suspend(). Außer allowThreadSuspension() sind die anderen Methoden auch in der Klasse Thread veraltet. Immer noch aktuell und nützlich sind die ThreadGroup-Methoden destroy() und interrupt().


class java.lang.ThreadGroup 
implements Thread.UncaughtExceptionHandler

  • final void destroy()
    Entfernt die Thread-Gruppe und alle Untergruppen. Die darin enthaltenen Threads müssen beendet worden sein. Eine IllegalThreadStateException wird ausgelöst, wenn die Gruppe nicht leer ist oder wenn die Gruppe schon entfernt wurde.
  • final void interrupt()
    Unterbricht alle Threads in der Gruppe und den Untergruppen.
  • final void setDaemon( boolean daemon ) Ändert den Status der Thread-Gruppe. Diese Gruppeneigenschaft ist orthogonal zur Dämon-Eigenschaft einzelner Threads. Die Dämon-Gruppe wird entfernt, falls der letzte Thread stoppt oder die letzte Thread-Gruppe entfernt wurde.
  • final boolean isDaemon()
    Testet, ob die Thread-Gruppe eine Dämon-Gruppe ist. Eine Dämon-Thread-Gruppe wird automatisch entfernt, wenn der letzte Thread gestoppt oder zerstört wurde.

Kein join in einer Thread-Gruppe

Eine Thread-Gruppe kennt keine join()-Methode wie ein Thread, sodass es über eine einzelne Methode nicht möglich ist, das Ende aller Threads in einer Gruppe zu erkennen. Doch die Thread-Gruppe besitzt die nützliche Methode activeCount(), über die etwa die Anzahl aktiver Threads – inklusive der Threads in Untergruppen – in Erfahrung gebracht werden kann. Damit ist Folgendes denkbar:

void join( ThreadGroup tg ) throws InterruptedException 
{ 
  synchronized( tg ) 
  { 
    while ( tg.activeCount() > 0 ) 
      tg.wait( 10 ); 
  } 
}

Das alles kommt noch in einen synchronized-Block und in ein wait(), damit die Schleife nicht zu viel Zeit kostet.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Java ist auch eine Insel





Java ist auch eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Tipp
Zum Katalog: Coding for Fun





 Coding for Fun


 Buchempfehlungen
Zum Katalog: Objektorientierte Programmierung





 Objektorientierte
 Programmierung


Zum Katalog: Einstieg in Eclipse 3.4






 Einstieg in
 Eclipse 3.4


Zum Katalog: Java 6 lernen mit Eclipse






 Java 6 lernen
 mit Eclipse


Zum Katalog: NetBeans Platform 6






 NetBeans
 Platform 6


Zum Katalog: Java und XML






 Java und XML


Zum Katalog: Visual C# 2008






 Visual C# 2008


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2009
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, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de