Java FX
Multithreading
Entwicklung PC-Performance
III_POS_JAVA ▪ Multithreading ▪ Seite 2
Parallelisierung der Programme
▪ Nutzung der Prozessorleistung (Multi-Core) erfordert
Parallelisierung der Programme
Prozesse OS
Threading Programmierer
▪ Singleprozessoren „Quasiparallelität“ gesteuert durch
Scheduler
III_POS_JAVA ▪ Multithreading ▪ Seite 3
Was ist ein Thread?
▪ Ausführungsweg im Programm („Programmfaden“)
▪ Je Programm existiert mindestens ein Thread
Hauptthread wird vom OS gestartet
▪ Multithreading teilt die Ausführung in parallele Pfade
Unabhängige Threads
Untereinander abhängige Threads
▪ Ablauf ist von anderem Thread abhängig (z.B. startet erst, wenn
alle vorhergehenden parallelen Threads fertig sind)
▪ Gemeinsame Daten
▪ Threads können sich Ressourcen teilen
Gemeinsame Variablen
Unkoordinierte Zugriffe falsche Ergebnisse
Synchronisierung
III_POS_JAVA ▪ Multithreading ▪ Seite 4
Einsatzgebiete
▪ Flüssig bearbeitbare UI
▪ Zeitintensive Aufgaben laufen im Hintergrund
Mathematische Berechnungen
Aufwändige Algorithmen (z.B. Sortieren großer
Datenbestände)
Drucken
Netzwerkaktivitäten
▪ Neuerdings: Nutzung von sonst brach liegenden
Prozessorkernen
III_POS_JAVA ▪ Multithreading ▪ Seite 5
Multithreading und CPU[-Kerne]
▪ Nutzung aller Kerne
Thread 1
Thread 2
Thread 3
▪ Simulation durch Zeitscheibenverfahren
Scheduler
Thread 1
Thread 2
Thread 3
III_POS_JAVA ▪ Multithreading ▪ Seite 6
Grundanforderungen für Multithreading
▪ Entkopple parallele Abläufe soweit möglich
Abhängigkeiten „serialisieren“ parallele Threads
Gefahr von Deadlocks
▪ Seiteneffekte vermeiden Scheduler
Gemeinsame Ressourcen
ohne Konflikte nutzen Thread 1 Thread 2
Gemeinsame
Ressourcen
III_POS_JAVA ▪ Multithreading ▪ Seite 7
Abstrakte Klasse Thread und Interface Runnable
«interface»
[Link]
[Link]
+Thread() Creates a default thread.
+Thread(task: Runnable) Creates a thread for a specified task.
+start(): void Starts the thread that causes the run() method to be invoked by the JVM.
+isAlive(): boolean Tests whether the thread is currently running.
+setPriority(p: int): void Sets priority p (ranging from 1 to 10) for this thread.
+join(): void Waits for this thread to finish.
+sleep(millis: long): void Puts the runnable object to sleep for a specified time in milliseconds.
+yield(): void Causes this thread to temporarily pause and allow other threads to execute.
+interrupt(): void Interrupts this thread.
III_POS_JAVA ▪ Multithreading ▪ Seite 8
Beispiel yield()
▪ Bei jedem Durchlauf wird der Prozessor
zurückgegeben
Kooperative Vorgangsweise
public void run() {
for (int i = 0; i < lastNum; i++) {
[Link](" " + i);
[Link]();
}
}
III_POS_JAVA ▪ Multithreading ▪ Seite 9
Methode join() führt Threads wieder zusammen
▪ Was passiert, wenn lastNum 100 enthält?
public void run() { Thread Thread
Thread thread4 = new Thread( print100 printA
new PrintChar('c', 40));
[Link](); -char token -char token
try {
+getToken +getToken
for (int i = 1; i <= lastNum; i++) { [Link]()
+setToken +setToken
[Link](" " + i); +paintCompo +paintCompo
if (i == 50) [Link](); Wait for printA
-char
net token net
} to finish+mouseClicke +mouseClicke
} +getToken
d d
catch (InterruptedException ex) { +getToken +setToken printA finished
} +setToken +paintCompone
t
+paintComponet -char token
} +mouseClicked
III_POS_JAVA ▪ Multithreading ▪ Seite 10
Lebenszyklus eines Threads
III_POS_JAVA ▪ Multithreading ▪ Seite 11
Zustände eines Threads
- Waiting
- Ready
Wird von Scheduler bestimmt
- Running
- Dead
Wird von Programm bestimmt
III_POS_JAVA ▪ Multithreading ▪ Seite 12
Zustand Waiting detailliert
- Waiting
Yielding
- Ready - thread gibt freiwillig Ressource frei
- Running - geht sofort in Zustand Ready
- Dead
Sleeping
- thread gibt Ressource für definierte Zeit frei
- geht erst nach Ablauf der Zeit in Zustand Ready
Blocking
- thread gibt Ressource frei und wartet auf Ereignis
- geht erst nach Ereignis in Zustand Ready
III_POS_JAVA ▪ Multithreading ▪ Seite 13
Prioritäten von Threads
▪ Jeder Thread hat in Java eine Priorität
ein integer-Wert von 1 bis 10, wobei 1 die niedrigste und
10 die höchste Priorität darstellt
▪ Threads mit einer hohen Prioritäten werden vor Threads
mit einer niedrigen Priorität abgearbeitet
▪ Ein Thread erbt die Priorität des Threads, von dem er
erzeugt wird
▪ Mit der Methode setPriority() wird die Priorität eines
Threads gesetzt:
MAX_PRIORITY
NORM_PRIORITY
MIN_PRIORITY
▪ Die Methode getPriority() liefert den aktuellen Wert
III_POS_JAVA ▪ Multithreading ▪ Seite 14
Beenden von Threads
▪ Thread ist mit seiner Aufgabe fertig Ende
▪ Methode stop(), suspend(), destroy() sind
deprecated nicht mehr verwenden
Brutales Beenden kann zu inkonsistenten
Zuständen führen
▪ Besser kooperativ vorgehen
Methode interrupt() und isInterrupted
Probleme, wenn Thread nicht aktiv ist
▪ JVM versetzt Thread in RUNNABLE und löst
InterruptedException aus (löscht isInterrupted)
▪ In catch-Block Thread erneut unterbrechen
[Link]().interrupt()
III_POS_JAVA ▪ Multithreading ▪ Seite 15
Critical Section, Race Condition und Deadlock
▪ Race Condition
Konstellation, bei der das Ergebnis eines
Programmteils von der Reihenfolge der Verarbeitung
abhängt
▪ Critical Section
Bereich im Programm, bei dem mehrere Threads
auf gemeinsame Ressourcen zugreifen
▪ Deadlock
Blockade mehrerer Threads untereinander
III_POS_JAVA ▪ Multithreading ▪ Seite 16
Steuerung konkurrierender Zugriffe lock
▪ Zutritt in kritische Bereiche Sperre anderer
Threads
▪ Sperre ganzer Methoden mit synchronized
Kann zu starker Serialisierung und damit Verlust der
Nebenläufigkeit führen
▪ Anlegen von Sperrobjekten
Z.B. private final Object lock = new Object();
Nur Block über synchronized(lock) sperren
III_POS_JAVA ▪ Multithreading ▪ Seite 17
Signalisierung statt „Busy-Waiting“
▪ Kommunikation über wait(), notify() und notifyAll()
▪ Gut einsetzbar bei Producer/Consumer-Szenarien
▪ wait() versetzt Thread in Zustand WAITING
Maximalzeit kann mitgegeben werden
Prozessor wird frei
z.B. Consumer, wenn Puffer leer ist
▪ notify() weckt einen (beliebigen) wartenden Thread auf
(RUNNING)
▪ notifyAll() weckt alle wartenden Threads auf
Prüfung vor Verarbeitung erneut notwendig
III_POS_JAVA ▪ Multithreading ▪ Seite 18
Beispiel: Annäherung von PI
▪ Arbeitsaufwändiger Hintergrundprozess
Berechnung von PI über
Wahrscheinlichkeit
von x² + y² <= r²
Parallele Berechnungen (Core2) und Mittelwert
▪ Calculatorklasse
Parameterlose Workermethode zum Starten
Startmethode legt Thread an und startet ihn
Parameterübergabe per Konstruktor
III_POS_JAVA ▪ Multithreading ▪ Seite 19