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.8 Mit dem Thread verbundene Variablen Zur nächsten ÜberschriftZur vorigen Überschrift

Unterschiedliche Threads können ohne Probleme das gleiche Runnable ausführen, was auch ein übliches Szenario ist, wenn der Programmcode immer der gleiche ist. Doch auch wenn der Programmcode immer gleich bleibt, soll jedem Thread doch vielleicht ein eigener Speicherbereich zugeteilt werden, in dem er Informationen ablegen kann. Falls das Runnable-Objekt selbst eine Objektvariable hätte und pro Thread auf diese Weise ein neues Runnable-Objekt gebildet würde, wäre das kein Problem, doch müsste bei genau einem Runnable-Objekt und beliebig vielen Threads ein anderer Ort gefunden werden.


Galileo Computing - Zum Seitenanfang

11.8.1 ThreadLocal Zur nächsten ÜberschriftZur vorigen Überschrift

Die Lösung ist relativ einfach: Es müsste eine Datenstruktur geben, die jeden Current Thread mit einem Objekt assoziiert. Diese Struktur muss dann im Runnable-Objekt referenzierbar sein. Java bietet mit der Klasse java.lang.ThreadLocal eine Implementierung für thread-lokale Variablen (engl. thread-local storage [TLS]) an.


class java.lang.ThreadLocal<T>

  • ThreadLocal()
    Erzeugt eine neue Thread-lokale Variable.
  • void set( T value )
    Setzt den Wert für den lokalen Thread.
  • T get()
    Liefert den Wert, der mit dem aktuellen Thread verbunden ist.
  • protected T initialValue()
    Die Methode kann überschrieben werden und liefert dann den Anfangswert beim ersten Aufruf von get() ohne vorangehendes set(). Der Standard ist null.
  • void remove()
    Entfernt den Wert der Thread-lokalen Variable, um etwa Speicher freizumachen. Ein anschließendes get() liefert wieder den Wert aus initialValue().

Zählen mit thread-lokalen Variablen

Das folgende Beispiel soll ein Runnable definieren, das endlos zählt. Der Clou ist aber, dass der Zähler keine lokale Variable, sondern eine Thread-lokale Variable ist, die ThreadLocal verwaltet. Drei Threads sollen das gleiche Runnable abarbeiten: zwei neue Threads und der aktuell ausführende main-Thread.

Listing 11.29 com/tutego/insel/thread/ThreadLocalDemo.java

package com.tutego.insel.thread; 
 
public class ThreadLocalDemo 
{ 
  public static void main( String[] args ) 
  { 
    Runnable runnable = new SimpleRunnable(); 
    new Thread( runnable ).start(); 
    new Thread( runnable ).start(); 
    runnable.run(); 
  } 
} 
 
class SimpleRunnable implements Runnable 
{ 
  private static final ThreadLocal<Integer> mem = new ThreadLocal<Integer>() 
  { 
    @Override protected Integer initialValue() { return 1; } 
  }; 
 
  public void run() 
  { 
    while ( true ) 
    { 
      System.out.println( Thread.currentThread().getName() + 
                          ", " + mem.get() ); 
      mem.set( mem.get() + 1 ); 
    } 
  } 
}

Den Startwert legt die überschriebene Methode initialValue() mit 1 fest. Da ThreadLocal einen Zähler speichert, ist der Datencontainer mit Integer typisiert.

Die Ausgabe kann beginnen mit:

main, 1 
main, 2 
main, 3 
main, 4 
main, 5 
Thread-0, 1 
Thread-1, 1 
Thread-0, 2 
Thread-1, 2 
Thread-0, 3 
Thread-1, 3

Galileo Computing - Zum Seitenanfang

11.8.2 InheritableThreadLocal topZur vorigen Überschrift

Jeder Thread kann einen neuen Thread bilden, der dann Kind ist. Da die main-Funktion selbst von einem Haupt-Thread ausgeführt wird, wie das Beispiel zeigt, ist schon dieser Thread der Vater, der neue Unter-Threads bildet.

Mit der Klasse InheritableThreadLocal, die Unterklasse von ThreadLocal ist, kann das Kind vom Vater den gespeicherten Wert übernehmen. Das würde sonst nicht funktionieren, da der neue Thread ja ganz eigene Werte hat, aber mit InheritableThreadLocal bleibt dieser Wert erhalten und wird auf die Kinder vererbt.

Dass ein gestarteter Kind-Thread den Wert vom Vater-Thread übernimmt, zeigt das folgende Programm. Ein Thread gibt den geerbten Wert aus und setzt anschließend einen neuen Wert für ein Kind, das der Thread in die Welt entlässt.

Listing 11.30 com/tutego/insel/thread/InheritableThreadLocalDemo.java

package com.tutego.insel.thread; 
 
public class InheritableThreadLocalDemo 
{ 
  public static void main( String[] args ) 
  { 
    new InheritingThread().start(); 
  } 
} 
 
class InheritingThread extends Thread 
{ 
//  private static final ThreadLocal<String> mem = new ThreadLocal<String>(); 
  private static final InheritableThreadLocal<String> mem =  
                              new InheritableThreadLocal<String>(); 
 
  @Override public void run() 
  { 
    System.out.println( Thread.currentThread() + " bekommt " + mem.get() ); 
    mem.set( Thread.currentThread().getName() ); 
 
    new InheritingThread().start(); 
  } 
}

Die Ausgabe beginnt mit:

Thread[Thread-0,5,main] bekommt null 
Thread[Thread-1,5,main] bekommt Thread-0 
Thread[Thread-2,5,main] bekommt Thread-1 
Thread[Thread-3,5,main] bekommt Thread-2

Der erste Thread bekommt noch nichts von seinem Vater-Thread. Da jedoch der erste Thread den eigenen Namen in den Speicher von InheritableThreadLocal legt und dann der zweite neu gestartete Kind-Thread auf den Wert zugreift, empfängt er die Zeichenfolge »Thread-0«.

Wer zum Testen InheritableThreadLocal durch ThreadLocal ersetzt, wird merken, dass das Beispiel so nicht funktioniert.

ThreadLocal bei der Performance-Optimierung

Ein ThreadLocal ist eine schöne Klasse zur Performance-Optimierung. Sollen zum Beispiel zwei Threads große Datenmengen über einen zentralen Puffer lesen, müssten sie an diesem Puffer synchronisiert werden. Mit ThreadLocal kann je ein Puffer beim Thread gespeichert sein, und die Synchronisation kann entfallen. Da es im Allgemeinen wenige Threads gibt, ist die Anzahl paralleler Puffer klein. Performance-Interessierte können einen Blick auf StringCoding werfen, wie sie ThreadLocal beim Caching von (De)Kodierer-Objekten nutzt. Die Klasse String nutzt StringCoding bei der Byte/Zeichen-Kodierung. Verschweigen dürfen wir aber nicht, dass der Zugriff auch etwas kostet, sodass ein kleiner synchronisierter Bereich durchaus schneller sein kann.



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