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