Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und...

37
Java Threads Sebastian Werler

Transcript of Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und...

Page 1: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Java Threads

Sebastian Werler

Page 2: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Der Thread läuft...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b)Synchronisation mit notify und wait

Page 3: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Grundlagen von Java-Threads

Threads sind direkt in die Sprache integriert

Jedes Java-Programm führt mind. einen Thread aus (nämlich der, in dem die main()-Methode läuft)

Page 4: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Der Thread läuft...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b)Synchronisation mit notify und wait

c)Deadlocks

Page 5: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Threads erstellen und starten – Teil 1

Threads werden durch die Klasse Thread und das Interface Runnable aus dem Packet java.lang implementiert

2 Möglichkeiten Threads zu implementieren

(1) Von der Klasse Thread ableiten und run() überschreiben

(2) Interface Runnable und damit run() implementierenClass DateThread implements Runnable { public void run(){ … } ... }

Class MyThread extends Thread  { ... public void run(){ … } ... }

Page 6: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Threads erstellen und starten – Teil 2

Fall 1: Thread-Klasse erweitert: Aufruf der Methode start() startet Thread

start() ruft run() auf und wird danach beendet: nachfolgende Befehle können parallel zum erzeugten Thread fortfahren (hier: System.out.println(...) )

Page 7: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Threads erstellen und starten – Teil 3

Fall 2: Implementierung von Runnable-Interface Binden des Runnable-Objekts an Thread über

Konstruktor

danach wie bei Fall 1 Vorteil Schnittstellen-Implementierung:

flexibel es kann noch geerbt werden

Page 8: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Threads erstellen und starten – Teil 4

Zwei Threads laufen:

„main“-Thread

t1

t1

Page 9: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Die Threads laufen...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b)Synchronisation mit notify und wait

Page 10: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Eigenschaften und Zustände

Name: setName(string n), getName() Priorität: setPriority(int p), getPriority()

ein neu erstellter Thread übernimmt Priorität des erstellenden Threads

die Priorität ist eine Zahl zwischen Thread.MIN_PRIORITY (1) und Thread.MAX_PRIORITY (10)

normalerweise hat ein Thread die Priorität 5 (Thread.NORM_PRIORITY)

eine Änderung der Priorität kann (muss nicht) eine verändertes Scheduling-Verhalten zugunsten der höher priorisierten Threads mit sich bringen

Page 11: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Eigenschaften und Zustände

ThreadGroup: über Konstruktor setzbar, getThreadGroup()

Schließt Threads zu Gruppen zusammen: Alle Threads einer Gruppe können gleichzeitig

gestoppt werden Max. Prioritäten können für Gruppe festgelegt

werden Repräsentiert durch ein ThreadGroup-Objekt Enumeration über ThreadGroup möglich

Page 12: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Zustand eines Threads

create runningready dead

blocked

Scheduler wähltanderen Thread,bspw. auf Basis vonyield()

Scheduler wähltThread ausstart()

blockiert nicht mehr (Ende synchronized,

notify, notifyAll, E/A

fertig)

run-Methode endet „normal“ oder mit

error (RuntimeException)

blockiert (synchronized, sleep, join, wait, auf E/A

wartend)

Page 13: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Die Threads laufen...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b)Synchronisation mit notify und wait

Page 14: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Abbruch von Threads

Thread terminiert, wenn run() beendet ist (return) oder ein Fehler (RuntimeException) auftritt

der Aufruf der Instanzmethode interrupt() erwirkt das Setzen eines Statusflags und „bittet“ damit einen Thread zur Aufgabe mit der Methode isInterrupted() wird das

Statusflag abgefragt (liefert boolean-Wert) und es kann entsprechend reagiert (abgebrochen) werden

Page 15: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Abbruch von Threads

Thread terminiert, wenn run() beendet ist (return) oder ein Fehler (RuntimeException) auftritt

der Aufruf der Instanzmethode interrupt() erwirkt das Setzen eines Statusflags und „bittet“ damit einen Thread zur Aufgabe mit der Methode isInterrupted() wird das

Statusflag abgefragt (liefert boolean-Wert) und es kann entsprechend reagiert (abgebrochen) werden

Page 16: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Die Threads laufen...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b) notify und wait

Page 17: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Synchronisation – warum?

Threads kommunizieren über gemeinsame Daten

lesen Threads Daten nur, so ist keine Synchronisation notwendig

Was passiert aber, wenn mehrere Threads Schreiboperationen auf eine Variable parallel ausführen? Inkonsistenzen können entstehen, wenn

Operationen nicht atomar sind Zugriff muss geregelt werden: Synchronisation! Java hat das Monitorkonzept implementiert

Page 18: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Die Threads laufen...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b) notify und wait

Page 19: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Das Schlüsselwort synchronize

synchronize realisiert das Monitorkonzept: Ein Monitor ist die Kapselung eines kritischen Bereichs,

mithilfe einer automatisch verwalteten Sperre Mit Hilfe des Schlüsselworts können komplette Methoden

oder Code-Blöcke mit einem gewünschten Objekt zur Sperre geschützt werden, Sperre über Code-Blöcke kann granularer sein. Methode synchronisiert:

Codeblock überein Objekt (einObjekt)synchronisiert:

Page 20: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Das Schlüsselwort synchronize

Beim Eintreten in einen mit synchronize geschützten Block oder einer mit synchronize deklarierten Methode wird eine Sperre gesetzt (auf das Objekt)

Diese Sperre wird erst beim Austreten aus dem Block/der Methode wieder entfernt (Freigabe auch durch RuntimeException möglich)

Page 21: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Das Schlüsselwort synchronize

andere Threads die den geschützten Bereich/Methode betreten wollen werden blockiert und müssen solange warten, bis die Sperre wieder aufgehoben wurde

so lange die Sperre existiert werden die blockierten Threads vom Scheduler nicht berücksichtigt

Page 22: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Inhalt

1.Grundlagen von Java Threads

2.Threads erstellen und starten

3.Die Threads laufen...

1.Eigenschaften und Zustände

2.Join

3.Abbruch (Interrupt)

4. Synchronisationa)Schlüsselwort synchronized

b) notify und wait

Page 23: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Sync über notify() und wait()

Quelle: http://openbook.galileocomputing.de/javainsel7/javainsel_10_006.htm#mjaea91b9f9b6c9682fbaceabd6012eb0c

Page 24: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Sync über notify() und wait()

liefert Warteliste für Threads (eine Wartemenge, keine Warteschlange im Sinne von FIFO)

über java.lang.Object besitzt jedes Objekt diese Methoden

dürfen nur aufgerufen werden, wenn eine Sperre auf ihr Ziel gesetzt wurde, d. h. innerhalb eines synchronized-Blocks/-Methode

Page 25: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

wait()

Durch den Aufruf von wait() wird der Thread in eine interne Warteliste (bzw. Wartemenge) des Aufruf-Objekts gestellt;

Sperre auf dem Aufrufobjekt wird temporär entfernt

Auch eine Angabe von Wartezeit ist möglich

Page 26: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

notify() und notifyAll()

Weckt einen (notify()) oder alle (notifyAll()) wartenden Thread(s) und entfernt ihn damit aus der Objektwartemenge

Keine Zusage, welcher Thread aus der Menge geweckt wird (geweckt bedeutet nicht automatisch, dass der Scheduler diesen Thread auch gleich auswählt)

Temporär entfernte Sperren werden wieder gesetzt

Page 27: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Beispiel: Erzeuger-Verbraucher

Es soll eine Erzeuger-Verbraucher-Beziehung implementiert werden, wobei beide jeweils als Thread laufen

Erzeuger produziert Integer, die der Verbraucher abfragt

Synchronisation über einen Puffer: Erzeuger schreibt über erzeugen() einen Wert in den Puffer, den der Verbraucher über verbrauchen() entnehmen kann

P 23

EE V

Page 28: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Klasse Puffer

Page 29: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Klasse Erzeuger

Page 30: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Klasse Verbraucher

Page 31: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Klasse ErzeugerVerbraucher

Page 32: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Ausgabe

Page 33: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Was passiert mit notify() statt notifyAll()

Dann kann es zu Deadlocks kommen, wenn der falsche Thread geweckt wird

Beispiel: Der Puffer ist zu Beginn leer. Die Threads V1 und V2 werden nacheinander vom Scheduler ausgewählt

und wollen jeweils ein Element aus dem Puffer verbrauchen. Da dieser leer ist, werden sie in die Warteliste des Puffers aufgenommen (wait()). Der Thread E1 bekommt Ausführungszeit und legt einen Wert in den Puffer und weckt V1 (notify()). E1 ist weiterhin in Ausführung und will wieder einen Wert in den Puffer legen. Dort ist aber bereits ein Wert, so dass auch E1 warten muss. Der Thread E2 wird ausgeführt, wird aber auch schlafen gelegt, da immer noch ein Wert im Puffer liegt (und er als Erzeuger aber einen neuen Wert hineinlegen wollte). V1 wird nun vom Scheduler ausgewählt: dieser Thread liest den Wert aus dem Puffer und weckt V2. V1 macht weiter und will wieder einen Wert aus dem Puffer lesen, da aber nun keiner mehr enthalten ist, muss V1 wieder warten. V2 wird mit Ausführungszeit bedacht und will so auch wieder einen Wert lesen. Da aber kein Erzeuger einen Wert in den Puffer geschrieben hat (beide Erzeuger-Threads befinden sich in der Warteliste und warten auf ein notify), kann auch kein Wert gelesen werden und auch V2 muss warten. So befinden sich nun alle Threads in der Warteliste des Puffer-Objekts und so kann auch kein Thread mehr geweckt werden. NotifyAll() verhindert diesen Zustand, da alle in der Warteliste befindlichen Threads geweckt werden und zu nach gewisser Zeit ein „richtiger“ Thread (in diesem Beispiel ein Erzeuger) Ausführungszeit vom Scheduler zugeteilt bekommt.

Page 34: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Einfach immer notifyAll() nutzen?

Ja. Auf jeden Fall dann nutzen, wenn:

Threads mit unterschiedlichen Wartebedingungen (Puffer ist voll, Puffer ist leer) in der Warteschlange sind: ein falscher Thread könnte geweckt werden

mehrere Threads zur Weiterarbeit geeignet sind

Page 35: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Weitere Sperren

Seit Java 5 gibt es noch weitere Sperren: Schnittstelle Lock (lock() und unlock()):

Implementierung: ReentrantLock, erzeugt Lock-Objekte die kritische Bereiche sperren können

Speziellere Sperren möglich (z. B. nur Schreibsperre) durch Spezialisierungen der Schnittstelle (ReentrantReadWriteLock mit u. a. der Methode readLock())

Page 36: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Literatur/Quellen

Thread, JavaDoc: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html

Lea, Doug: Concurrent Programming in Java, 2nd Edition, 2000, Addison-Wesley, Boston. (Für Fortgeschrittene: Prinzipien und Muster für nebenläufige Programmierung)

Ullenboom, Christian: Java ist auch eine Insel, OpenBook, http://openbook.galileocomputing.de/javainsel7/ (sehr gut geeignet für einen Einstieg in Java)

Schütte, Alois: Vorlesungsskript Parallel Programming, http://www.fbi.h-da.de/~a.schuette/Vorlesungen/ParallelProgramming/

Krüger, Guido: Handbuch der Java-Programmierung 2005, Addison-Wesley, München. (Umfangreiches Werk zu Java)

Page 37: Java Threads Sebastian Werler. Inhalt 1. Grundlagen von Java Threads 2. Threads erstellen und starten 3. Der Thread läuft... 1. Eigenschaften und Zustände.

Vielen Dank für die Aufmerksamkeit.

Fragen?