Threads - Radar ZHAW

Werbung
INE2
Threads Einführung
■ Einführung in Prozesse und Threads (Faden)
■ Single- und Multithreading in Java
■ Java Threads: Erzeugung, Methoden und Zustände
■ Threadsicherheit
Einführung
School of Engineering
© G. Burkert, K. Rege, ZHAW
2 von 46
Einführung
■ Die meisten Computer haben nur einen Prozessor (CPU)
■
Kann einen Befehl nach dem anderen ausführen
■ Trotzdem: die Ausführung von mehreren Programmen gleichzeitig ist möglich:
■
■
Ein Benutzer mit mehreren Programmen
Mehrere Benutzer an einem Rechner
■ Wie ist das möglich?
■
■
■
■
■
Ein laufendes Programm nennt
man einen Prozess
Prozessor lässt eine gewisse Zeit
P1:
P1:
(z.B. 10 ms) einen Prozess laufen und
wechselt dann zum nächsten
P2:
P2:
Hat ein Prozess „gerade nichts zu tun“
P3:
P3:
(z.B. Warten auf Input), so erhält er auch
keine CPU-Zeit
Solange die Belastung im Rahmen bleibt,
merkt ein Benutzer kaum, dass auch
andere Prozesse laufen
Wird durch das Scheduling des Betriebssystem
gesteuert
School of Engineering
Run
Run
Wait
R
R
Wait
R
R
R
R
R
R
R
R
R
R
Wait
R
R
Wait
Wait
Wait
R
R
R
R
Wait
R
R
R
R
R
R
Wait
t
Alle Prozesse pseudoparallel in einer
CPU ausgeführt
© G. Burkert, K. Rege, ZHAW
3 von 46
Multitasking/Multiprozessing
■ Prozess = Programm in Ausführung, Behälter für Ressourcen
■ Ein Systeme mit (scheinbar) gleichzeitig laufenden Prozessen nennt man
Multitasking-Systeme
■
■
■
■
Alle gängigen modernen Betriebssysteme sind
Multitasking-Systeme (Unix, Linux, WinXP...)
Jeder Prozess hat seinen eigenen
Arbeitsspeicherbereich (Ressourcen)
Datenaustausch zwischen Prozessen
relativ aufwendig
Das Umschalten zwischen 2 Prozessen ist
ebenfalls aufwändig, da der komplette Zustand
gespeichert und ein anderer Zustand geladen
werden muss
Prozess
Ressourcen
■ Idee: auch innerhalb eines Prozesses parallele
Ausführung ermöglichen
School of Engineering
© G. Burkert, K. Rege, ZHAW
4 von 46
Multithreading
■ Prozess = Behälter für Ressourcen
■ Thread = Programmteil in Ausführung
■ Daneben gibt es auch Parallelität innerhalb
eines Prozesses -> Multithreading
■
■
■
■
Thread: ein Programmteil, parallel zu den
anderen Programmteilen abläuft
Threads eines Programms teilen sich
den Arbeitsspeicherbereich
Æ Kommunikation via gemeinsame
Variablen/Objekte möglich
Umschalten zwischen Threads eines
Programms ist sehr schnell
Man unterscheidet zwischen single-threaded
und multi-threaded Programmen
School of Engineering
© G. Burkert, K. Rege, ZHAW
Prozess
Ressourcen
Thread A Thread B
5 von 46
Zeitscheibenschema: Timeslice
■ Jedem Thread wird ein "fairer" Anteil
(eine Zeitscheibe) an Rechenzeit zur
Verfügung gestellt
1
2
CPU Zeit
1
■ Strategien zur Rechenzeitvergabe
3
■ Kooperative Mutithreading
■
■
Threads
■ Preemptive Multithreading
■
■
School of Engineering
Der Thread gibt die Kontrolle selber wieder ab
Nachteil:
■ ein "unfairer" Thread kann das ganze
System blockieren
Nach Ablauf dieser Zeit wird ihm die Kontrolle
automatisch wieder entzogen
Nachteile:
■ das zeitliche Verhalten ist nicht mehr
vorhersagbar
■ Notwendigkeit des Synchronisation bei
gemeinsam zugegriffen Variablen
© G. Burkert, K. Rege, ZHAW
6 von 46
Mehrkernprozessoren
■ Heute werden immer mehr Mehrkerprozessoren eingesetzt
■ Jeder Kern ist dabei eigentlich ein eigenständiger Prozessor der
■
■
selbständig ein Programm/einen Prozess abarbeiten kann
Mit anderen Kernen sich jedoch die Ressourcen (Bus, Memory, Caches, etc) teilen muss
echte Parallelität
■ Die auf dem Datenblatt angegebene Rechenleistung wird nur erreicht, wenn alle
Kerne gleichzeitig parallel arbeiten können
■ Oftmals ein einzelnes Programm, das
hauptsächlich läuft
■ Viele Programme sind noch "Single Threaded".
■ Um die Rechenleistung zu erreichen, muss
jedoch multithreaded programmiert werden
Intel Core 2 Duo E6750 dual-core processor.
School of Engineering
© G. Burkert, K. Rege, ZHAW
7 von 46
Single-/Multithreading in Java
School of Engineering
© G. Burkert, K. Rege, ZHAW
8 von 46
Single-/Multithreading in Java
Bis jetzt:
■ Sie haben in Java immer single-threaded programmiert
Java unterstützt Multithreading:
■ Wenn man „nichts explizit tut“, läuft ein Java Programm single-threaded ab
■ Es gibt aber diverse Situationen, in welchen man ein (Java-)Programm jedoch
multi-threaded implementieren muss, um einen sinnvollen Programmablauf zu
erhalten (nicht nur bessere Performance)
■ Aus Sicht des Betriebssystems ist auch ein multi-threaded Java-Programm
immer noch nur ein Prozess (Ressource-Container)
■ Das Umschalten zwischen den Threads ist Aufgabe der Java Virtual Machine
(JVM mit Hilfe des BS!)
School of Engineering
© G. Burkert, K. Rege, ZHAW
9 von 46
Beispiel von Threads
public class Bouncer1 extends JFrame implements ActionListener
private Button start, stop;
private Ball ball;
{
public void initComponents() {
start = new Button("Start");
add(start);
start.addActionListener(this);
stop = new Button("Stop");
add(stop);
stop.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == start) {
Graphics g = getGraphics();
ball = new Ball(g, getBackground());
ball.display();
}
if (event.getSource() == stop) {
ball.anhalten();
Referenz
Referenzauf
aufGraphics
Graphicsund
undBackgroundBackground}
Farbe
im
Ball
speichern,
damit
Farbe im Ball speichern, damitwir
wir
}
ausserhalb
von
paint
direkt
im
Ball
ausserhalb
von
paint
direkt
im
Ball
}
zeichnen
zeichnenkönnen
können
School of Engineering
© G. Burkert, K. Rege, ZHAW
10 von 46
...Beispiel von Threads
public void display() {
for (int n = 1; (n< 200 && weiterSo); n++) {
class Ball {
g.setColor(Color.BLACK);
private Graphics g;
g.drawRect(rectLeftX, rectTopY, rectRightX private Color bgColour;
rectLeftX, rectBottomY-rectTopY);
private int xChange = 2;
g.setColor(bgColour);
verstecken
private int yChange = 3;
g.fillOval (x, y, diameter, diameter);
verstecken
private int diameter= 20;
if (x + xChange < rectLeftX){
private boolean weiterSo = true;
xChange = -xChange;
private int rectLeftX = 50,
}
rectRightX = 350;
if (x + diameter > rectRightX){
Randprivate int rectTopY = 50,
RandxChange = -xChange;
bereich
rectBottomY = 350;
}
bereich
private int x = rectLeftX + xChange;
überif (y < rectTopY){
überprivate int y = rectTopY + yChange;
yChange = -yChange;
prüfen
prüfen
}
public Ball(Graphics graphics,
if (y + diameter > rectBottomY){
Color bg) {
yChange = -yChange;
g = graphics;
}
bgColour = bg;
x = x + xChange;
verschieben
}
verschieben
y = y + yChange;
g.setColor(Color.red);
g.fillOval (x, y, diameter, diameter);
try {
Thread.sleep(20);
20
ms
Referenz
auf
Graphics
intern
}
20 ms
Referenz auf Graphics intern
catch (InterruptedException e) {return;}
schlafen
gespeichert,
damit
wir
ausserhalb
schlafen
gespeichert, damit wir ausserhalb
} // end for
von
} // end display
vonpaint
paintzeichnen
zeichnenkönnen
können
Rahmen
Rahmen
zeichnen
zeichnen
public void anhalten(){
weiterSo = false;
} } // end Ball
School of Engineering
© G. Burkert, K. Rege, ZHAW
11 von 46
...Beispiel von Threads: Problem
1. Fall: Single-Threaded:
Ein
Einrechenintensives
rechenintensivesHauptprogramm
Hauptprogrammkann
kannGUI
GUI
völlig
blockieren
völlig blockieren
Æ
ÆAbhilfe
AbhilfeÆ
ÆMultithreading
Multithreading
■ Klick auf „Start“-Button
■ Ball-Object ball wird kreiert
■ ball.display() wird aufgerufen
■ display()-Methode verschiebt Ball
und wartet 50 ms
■ display()-Methode wird erst nach 10
s (200x50ms) wieder verlassen
■ Während dieser Zeit können keine
Events verarbeitet werden (z.B. Knöpfe
gedrückt)
■ Erst nach Verlassen der display()Methode kann wieder ein Event
empfangen werden
School of Engineering
© G. Burkert, K. Rege, ZHAW
12 von 46
...Beispiel von Threads: Lösung
■Das Ball-Objekt läuft in seinem eigenen Thread und das
JFrame (GUI) bleibt für Benutzereingaben verfügbar
Thread
Vorgehen:
■Die Klasse Ball wird von der Klasse Thread abgeleitet
■Dabei werden die Methoden run() und start() vererbt
Ball
■Die run()-Methode ist der Teil des Balls, der in einem
eigenen Thread läuft -> überschreiben und Zeichnen des Balls
■Die start() Methode (geerbt von Klasse Thread) startet den Thread
■Aus Sicht des JFrames:
■
■
■
■
Kreieren des Ball-Objekts: Ball ball = new Ball(g,getBackground());
Starten des Threads: ball.start(); -> ruft die run() Methode auf
Ab diesem Moment „läuft“ der Ball unabhängig
Stoppen des Threads Æ Signalisierung via Variable „weiterSo“
School of Engineering
© G. Burkert, K. Rege, ZHAW
13 von 46
...Beispiel von Threads: Lösung
public class Bouncer2 extends JFrame implements ActionListener
private Button start, stop;
private Ball ball;
{
public void initComponents() {
start = new Button("Start");
add(start);
start.addActionListener(this);
stop = new Button("Stop");
add(stop);
stop.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == start) {
Graphics g = getGraphics();
ball = new Ball(g, getBackground());
ball.start();
}
Run-Methode
Run-Methodeininneuem
neuemThread
Thread
if (event.getSource() == stop) {
starten
starten
ball.anhalten();
}
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
14 von 46
...Beispiel von Threads: Lösung
Ball
Ballerweitert
erweitert
Klasse
KlasseThread
Thread
class Ball extends Thread {
private Graphics g;
private Color bgColour;
private int xChange = 2;
private int yChange = 3;
private int diameter= 20;
private int rectLeftX = 50,
rectRightX = 350;
private int rectTopY = 50,
rectBottomY = 350;
private int x = rectLeftX + xChange;
private int y = rectTopY + yChange;
public Ball(Graphics graphics,
Color bg) {
g = graphics;
bgColour = bg;
}
Endlosschleife;
Endlosschleife;
Abbruch durch
Abbruch durch
"Abbruch"
"Abbruch"
run-Methode
run-Methodeim
im
Thread
wird
hier
Thread wird hier
überschrieben
überschrieben
@Override
public void run() {
while(!isInterrupted()) {
g.setColor(Color.BLACK);
g.drawRect(rectLeftX, rectTopY, rectRightX rectLeftX, rectBottomY-rectTopY);
g.setColor(bgColour);
g.fillOval (x, y, diameter, diameter);
if (x < rectLeftX){
xChange = -xChange;
}
if (x + diameter > rectRightX){
xChange = -xChange;
}
if (y < rectTopY){
yChange = -yChange;
}
if (y + diameter > rectBottomY){
yChange = -yChange;
}
x = x + xChange;
y = y + yChange;
g.setColor(Color.red);
g.fillOval (x, y, diameter, diameter);
try {
Thread.sleep(20);
}
catch (InterruptedException e) {return;}
} // end while
} // end display
public void anhalten(){
interrupt();
} } // end Ball
School of Engineering
© G. Burkert, K. Rege, ZHAW
15 von 46
...Beispiel von Threads: Lösung
2. Fall: Multi-Threaded:
■ Bouncer2 läuft im Haupt-Thread
■ Jeder kreierte Ball läuft nach dem Aufruf
der start()-Methode in seinem
eigenen Thread
■ Ein Thread läuft so lange, bis seine
run()-Methode fertig ist
■ Man kann auch mehrere Bälle
erzeugen…
■ …nur letzter Thread kann gestoppt
werden
School of Engineering
© G. Burkert, K. Rege, ZHAW
16 von 46
Erzeugen von Java Threads
School of Engineering
© G. Burkert, K. Rege, ZHAW
17 von 46
Erzeugen von Java Threads
Wie macht man aus einem Objekt einen Thread:
Thread
■ Die Klasse wird von Thread abgeleitet
■
■
■
class Ball extends Thread {...}
Die Klasse Ball muss die Methode run() überschreiben
Die Erzeugung eines Objekts der Klasse Ball erzeugt automatischen einen Thread
Ball ball = new Ball(...);
ball.start(); // startet die run-Methode
Ball
■ Die Klasse implementiert das Interface Runnable
■
■
■
■
class Ball implements Runnable {...}
Die Klasse Ball muss die Methode run()
implementieren
Ein Objekt der eigenen Klasse erzeugen und
daraus einen Thread erzeugen:
Ball ball = new Ball(...);
Thread myThread = new Thread(ball);
mythread.start(); // startet die run-Methode im ball
Geeignet, wenn die Klasse bereits eine Oberklasse hat
School of Engineering
© G. Burkert, K. Rege, ZHAW
<<interface>>
Runnable
Figure
Ball
18 von 46
…Erzeugen mittels extends Thread
public class Counter extends Thread {
……
@Override
public void run() {
....
}
}
Thread
Ball
Hauptprogramm (z.B. JFrame)
class myApplic extends JFrame {
Thread t1 = new Counter(…);
public void init(){
……………
……………
t1.start();
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
19 von 46
Beispiel: Erben von Basisklasse Thread
public static void main(String[] args) {
import java.lang.*;
int i1 = Integer.valueOf(args[0]);
import java.util.*;
int i2 = Integer.valueOf(args[1]);
System.out.println(i1+","+i2);
public class Shubiduh extends Thread {
String word="";
Thread t1 = new shubiduh("Shubi", i1)
int waitfor=0;
t1.start();
Thread t2 = new shubiduh("Duh", i2)
public Shubiduh(String shubiduhstring, int
sleeptime) {
t2.start();
}
word=shubiduhstring;
waitfor=sleeptime;
}
@Override
public void run(){
■ eigene Klasse erbt von Thread
■ die Methode run überschreiben
try {
for (int i=0; i<10; i++) {
System.out.println(word);
if(waitfor>0) sleep(waitfor);
}
} catch (InterruptedException e) {}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
20 von 46
…Erzeugen von Java Threads mit Runnable
public class Counter extends SomethingElse
implements Runnable {
……
public void run() {
....
}
}
<<interface>>
Runnable
Figure
Ball
Hauptprogramm (z.B. JFrame)
class myApplic extends JFrame {
Counter c1 = new Counter(…);
Thread t1 = new Thread(c1);
public void init(){
……………
……………
t1.start();
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
21 von 46
Beispiel: Implementation Interfaces Runnable
public void run(){
import java.lang.*;
try {
import java.util.*;
for (int i=0; i<10; i++) {
System.out.println(word);
public class Shubiduh implements Runnable {
if(waitfor>0) runner.sleep(waitfor);
String word="";
}
int waitfor=0;
} catch (InterruptedException e) {}
Thread runner;
}
public Shubiduh(String shubiduhstring, int
sleeptime) {
word=shubiduhstring;
waitfor=sleeptime;
■ eigene Klasse implementiert Runnable
■ die Methode run implementieren
}
public void start() {
■ die Methoden start implementieren
if (runner==null) {
runner = new Thread(this);
runner.start();
}
}
School of Engineering
■ wird angewandt, wenn von anderer
Klasse geerbt werden "muss"
■
MyClass extends JFrame implements
Runnable
© G. Burkert, K. Rege, ZHAW
22 von 46
Thread Methoden
School of Engineering
© G. Burkert, K. Rege, ZHAW
23 von 46
Thread Methoden
■ start()
■ static sleep(int ms)
■ static yield()
■ join()
■ setPriority(int pri)
■ int getPriority()
startet Thread
gerade ausgeführter Thread schläft für ms
Millisekunden; gibt Kontrolle an anderen Thread ab
gerade ausgeführter Thread übergibt
Kontrolle einem anderen Thread an
ein anderer Thread wartet auf die Beendigung des
Threads
Priorität des Threads auf pri setzen (vordefinierte
Werte: MAX_PRIORITY (10), MIN_PRIORITY (1),NORM_PRIORITY (5))
Priorität eines Threads auslesen
■ boolean isAlive()
gibt an, ob ein Thread noch/schon läuft
■ setDaemon(true);
macht aus dem Thread einen Daemon Thread
■ static currentThread(); hole eigenen aktuellen Thread
■ isInterrupted()
Abfrage ob Interrupt Flag gesetzt
■ interrupt()
Setzen des Interrupt Flags
■ stop()
■ suspend()
■ resume()
School of Engineering
hält Thread an (mit einer Exception), deprecated
unterbricht Ausführung des Threads, deprecated
lässt Thread weiterfahren, deprecated
© G. Burkert, K. Rege, ZHAW
24 von 46
Methode sleep
■generiert Interrupted Exception
Æ muss mit Try-Catch abgefangen werden!
try {Thread.sleep(50);}
catch (InterruptedException e) {...}
sleep ist static und kann deshalb auch im Hauptprogramm ausserhalb eines
Thread-Objektes benutzt werden
- Hauptprogramm wird nämlich auch in einem Thread ausgeführt; Zeit in
Millisekunden
Æ Thread.sleep(100);
Klassennamen
Klassennamenverwenden
verwenden! !
School of Engineering
© G. Burkert, K. Rege, ZHAW
25 von 46
Methode currentThread
■ Um (nicht-statische) Methoden aufzurufen, wenn man nicht von Thread erbt,
kann man sich mittels currentThread sich den aktuellen Thread geben lassen
Thread current = Thread.currentThread();
current.setPriority(1);
School of Engineering
© G. Burkert, K. Rege, ZHAW
26 von 46
Methode join
■ Ein Thread möchte u.U. warten bis ein
gestarteter mit seiner "Arbeit" fertig ist,
d.h. terminiert.
■ t.join() der aufrufende Thread wartet bis
der in t gespeicherte Thread terminiert
Thread t = new MyThread();
t.start();
…
t.join();
t.join()
t.join()
School of Engineering
© G. Burkert, K. Rege, ZHAW
27 von 46
Methode yield
■ yield gibt die Kontrolle ab;
■ wird innerhalb der run-Methode verwendet, wenn im Moment nichts gemacht
werden soll/muss
run() {
while(true) {
…
// nothing to do
yield();
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
28 von 46
Methode setDaemon
■ Ein Programm beendet erst, wenn alle seine Threads beendet sind
■
es muss "Buch" über alle erzeugten Threads geführt werden und alle müssen gestoppt werden
■ Einfacher
■
setDaemon(true) vor dem start() des Threads aufrufen
■
Programm wird auch beendet wenn noch Deamon Threads am Laufen sind;
Thread t = new MyThread();
t.setDaemon(true);
t.start();
School of Engineering
© G. Burkert, K. Rege, ZHAW
29 von 46
Unterbrechen von Threads: interrupt
■ stop()-Methode ab Java 1.2 deprecated Æ aktives stoppen eines Threads
sollte nicht mehr verwendet werden
■ stoppen eines Threads geht über die interrupt()-Methode
■
■
■
■
Setzt ein Interrupt-Flag im Thread (beendet den Thread nicht)
Muss via interrupted()-Methode abgefragt werden (zB innerhalb einer while-Schleife in der
run()-Methode)
Der Thread entscheidet, wie er auf das Interrupt-Flag reagieren soll
Schläft der Thread (sleep oder wait), so wird eine InterruptedException generiert
■sleep/wait gehört deshalb in ein entsprechendes try/catch Konstrukt:
try {
sleep(1000); // oder wait();
} catch (InterruptedException e) {
// Reaktion auf ein Aufruf von interrupt()
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
30 von 46
Zustände von Threads
School of Engineering
© G. Burkert, K. Rege, ZHAW
31 von 46
Zustandsdiagramm
runnable
runnable
suspend()
wait()
sleep()
yield()
running
running
new
new
blocked
blocked
start()
stop()
resume()
notify()
stop(),
run() fertig
stop()
stop()
dead
dead
School of Engineering
© G. Burkert, K. Rege, ZHAW
32 von 46
Zustände eines Threads
Ein Thread ist zu jedem Zeitpunkt in einem von 5 Zuständen:
■ New
Thread erzeugt (mit new), aber noch nicht gestartet (mit
start())
■ Running
Thread läuft
■ Runnable
Thread bereit zum laufen, aber anderer Thread läuft zur Zeit
■ Blocked
Thread kann zur Zeit nicht weiterfahren, z.B. wegen sleep
■ Dead
Thread ist fertig abgelaufen
Abfrage mit isAlive():
■ true
Running, Runnable oder Blocked
■ false
New oder Dead
School of Engineering
© G. Burkert, K. Rege, ZHAW
33 von 46
Threadsicherheit
School of Engineering
© G. Burkert, K. Rege, ZHAW
34 von 46
Threadsicherheit (thread safety)
■ Teile eines Computerprogramms können zum gleichen Zeitpunkt mehrmals
ausgeführt werden.
■ Dabei handelt es sich oft um eine Komponente oder auch nur um eine
Funktion/Methode des Programms.
■ Threadsicherheit ist eine Eigenschaft von Softwarekomponenten
■
■
■
eine Komponente gleichzeitig von verschiedenen Programmbereichen mehrfach ausgeführt werden
kann
ohne dass diese sich gegenseitig behindern
das korrekte Resultat auch in allen Fällen liefert
School of Engineering
© G. Burkert, K. Rege, ZHAW
35 von 46
Problem aus dem Alltagsleben
■ Zu viel Milch heute
typischer
typischerWG
WG
Kühlschrankinhalt
Kühlschrankinhalt
School of Engineering
© G. Burkert, K. Rege, ZHAW
36 von 46
Analyse des Problems
■ Eine geteilte Ressource (Kühlschrank/Konto) wird "gelesen" und anhand dieser
Information wird eine Aktion ausgelöst (Milch kaufen).
■ Die Aktion dauert aber eine gewisse Zeit und deshalb hat in der Zwischenzeit ein
anderer ebenfalls die Ressource gelesen und die Aktion ausgelöst.
Beispiel Kontoeinzahlung
Thread 1
Thread 2
k = readKonto();
k = readKonto();
k = k + 20;
k = k + 50;
writeKonto(k);
writeKonto(k);
Thread
Thread
Wechsel
Wechsel
School of Engineering
© G. Burkert, K. Rege, ZHAW
37 von 46
Threadsicherheit
■ Eine Methode ist Threadsicher wenn
■
■
auf geteilte Ressourcen (Variablen) nur lesend zugegriffen wird
schreibend nur auf lokale Variablen zugegriffen wird
■ Falls Methoden/Klassen in einem multithreaded Kontext verwendet werden
sollen, versuchen, möglichst ohne Instanzvariablen (oder statische Variablen)
auszukommen (auf diese schreibend zuzugreifen).
■ Falls dies nicht möglich ist, dann müssen Threads "synchronisiert" werden
-> Kritischer Bereich
School of Engineering
© G. Burkert, K. Rege, ZHAW
38 von 46
Kritischer Bereich
■ In Java kann mit synchronized eine Methode
als kritischer Bereich definiert werden
■ Der kritischer Bereich wird so als Ganzes ausgeführt
public synchronized int deposit(double amount) {
double k = readKonto();
k += amount;
writeKonto();
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
39 von 46
Threadsicherheit und Swing
■ Swing ist nicht Thread Safe!
■ Änderungen am GUI ausserhalb des main-Threads können zu
Inkonsistenzen/Fehlern führen.
public class MyThread extends JFrame implements Runnable {
Separater
SeparaterThread,
Thread,der
der
JTextField tf;
Werte
ins
GUI
schreibt
Werte ins GUI schreibt
int i;
public MyThread(JTextField tf) {this.tf = tf;}
führe später (unter
führe später (unter
public void run() {
Kontrolle
Kontrollevon
vonSwing)
Swing)aus
aus
try {for (i = 0; i < 100; i++) {
final String s = Integer.toString(i);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Anonyme
AnonymeKlasse
Klassebzw.
bzw.
tf.setText(s);
Methode
um
Wert
inin
Methode
um
Wert
}
JTextField
JTextFieldzu
zusetzen
setzen
});
Thread.sleep(100);
}
}
catch (Exception e) {}
}
void initComponents(){
. . .
Thread thread = new Thread(this);
Starten des Threads
Starten des Threads
thread.setDaemon(true);
thread.start();
}
}
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/initial.html
School of Engineering
© G. Burkert, K. Rege, ZHAW
40 von 46
Zusammenfassung
■ Prozess und Thread
■ Single/Multithreaded Java Programme
■ Erzeugung von Threads
■ Thread Methoden
■ Thread Zustände
■ Threadsicherheit
School of Engineering
© G. Burkert, K. Rege, ZHAW
41 von 46
Noch Fragen?
School of Engineering
© G. Burkert, K. Rege, ZHAW
42 von 46
Lernaufgabe
■ Schreiben Sie eine Java-Konsolen Anwendung, die
In Ihrem Constructor 2 Threads der Klasse MyThread erzeugt und aktiviert
public class ZweiThreads {
public static void main(String[] args) {
ZweiThreads appl = new ZweiThreads();
}
ZweiThreads() {
// Constructor
MyThread t1 = new MyThread("**** Hallo ich bin Thread1");
MyThread t2 = new MyThread("***************** Hallo ich bin
Thread2");
………………………
}
}
■ Klasse MyThread soll den im Konstructor übergegebenen String 100x auf der System-Konsole
************************ Hallo ich bin Thread2, i = 0
ausgeben (mit Systen.out…. ).
************************ Hallo ich bin Thread2, i = 1
************************ Hallo ich bin Thread2, i = 2
■ Das Hauptprogramm und beide Threads
************************ Hallo ich bin Thread2, i = 3
************************ Hallo ich bin Thread2, i = 4
sollen parallel ablaufen.
**** Hallo ich bin Thread1, i = 0
**** Hallo ich bin Thread1, i = 1
**** Hallo ich bin Thread1, i = 2
■ Beide Lösungsvarianten
**** Hallo ich bin Thread1, i = 3
**** Hallo ich bin Thread1, i = 4
■ Optional: warten bis beide beendet
**** Hallo ich bin Thread1, i = 5
■
************************ Hallo ich bin Thread2, i = 5
**** Hallo ich bin Thread1, i = 6
************************ Hallo ich bin Thread2, i = 6
**** Hallo ich bin Thread1, i = 7
************************ Hallo ich bin Thread2, i = 7
School of Engineering
© G. Burkert, K. Rege, ZHAW
43 von 46
Lernaufgabe: Lösung
■Java-Konsole-Applikation, die
■ In Ihrem Konstruktor 2 Threads der Klasse MyThread erzeugt und startet
public class ZweiThreads {
public static void main(String[] args) {
ZweiThreads appl = new ZweiThreads();
}
ZweiThreads() {
// Constructor
MyThread t1 = new MyThread("**** Hallo ich bin Thread1");
MyThread t2 = new MyThread("***************** Hallo ich bin Thread2");
t1.start();
t2.start();
System.out.println("=============== Threads started! ========");
// fakultativ: warten, bis beide Threads beendet werden
try {
t1.join();
t2.join();
} catch (Exception e ) {}
System.out.println("=============== Threads beendet =========!");
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
44 von 46
…Lösung mit Thread
class MyThread extends Thread {
String message;
boolean weiterSo=true; // Abbruch-Flag
MyThread(String msg) {
message = msg;
}
// Constructor: Message übernehmen
public void run () {
// Thread-RUN-Methode
Thread-Schleife
Thread-Schleife
for (int i=0; (i<100 && !isInterrupted()); i++){
System.out.println(message + ", i = " + i);
//
yield();
// schauen Sie, was passiert, wenn aktiviert
}
}
public void abbrechen(){
interrupt();
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
45 von 46
…Lösung mit Runnable
class MyRunnable implements runnable{
String message;
Thread runner;
boolean weiterSo=true; // Abbruch-Flag
MyThread(String msg) {
message = msg;
}
// Constructor: Message übernehmen
public void run () {
// Thread-RUN-Methode
for (int i=0; (i<100 && runner.isInterrupted(); i++){
System.out.println(message + ", i = " + i);
//
yield();
// schauen Sie, was passiert, wenn aktiviert
}
}
public void start() {
if (runner==null) {
runner = new Thread(this);
runner.start();
}
}
public void abbrechen(){
runner.interrupt();
}
}
School of Engineering
© G. Burkert, K. Rege, ZHAW
46 von 46
Herunterladen