Parallel Programming Thread Synchronization
Heute 1. Lösung zu Assignment 2 2. Erstellen und Starten von Threads in Java 3. Das synchronized Schlüsselwort in Java 4. Ausblick auf Assignment 3
1. – ASSIGNMENT 2 Live
2. – STARTEN VON THREADS IN JAVA
Threads erstellen Klasse java.lang.Thread Zwei Möglichkeiten : 1. Interface Runnable 2. Thread. run überschreiben
Interface Runnable public interface Runnable { void run(); } //in MyProcess.java public class MyProcess implements Runnable { void run() { //what I want this thread to do System.out.println(Hello from thread); } } //where you start the thread MyProcess mp = new MyProcess(); Thread t = new Thread(mp); t.start();
Thread.run überschreiben //in MyProcess.java public class MyProcess extends Thread { void run() { //what I want this thread to do System.out.println(Hello from thread); } } //where you start the thread MyProcess mp = new MyProcess(); mp.start();
Was ist besser? Thread.run + Einfacher aufzusetzen + Mehr Kontrolle über das Thread - Objekt - Weniger flexibel ( Vererbung ) Runnable Interface + Steht Vererbung nicht im Weg + Ist nicht an Threads gebunden - Benötigt einen Schritt mehr zum Aufsetzen
Threads auf Eis try { //doze a random time (0 to 0.5 secs) to simulate workload Thread.sleep( (int)(Math.random()*500) ); } catch (InterruptedException e) { … } Thread. sleep ( long ) versetzen den aktuellen Thread für mindestens x Millisekunden in den sleep - Zustand. Wozu InterruptedExcpetion ?
Ohne InterruptedException Zeit Thread AThread B Thread.sleep(500) Katastrophe
Mit InterruptedException Zeit Thread AThread B Thread.sleep(500) Katastrophe
3. – SYNCHRONIZED
Intrinsic synchronized public class Buffer { public synchronized void write(int i) { … } public synchronized int read() { … } } Für Methoden Thread muss zunächst exklusiven lock erlangen Jede Klasse und jedes Objekt hat einen intrinsic lock Schliessen sich gegenseitig aus ( mutual exclusion ), weil beide this als lock verwenden
synchronized Block public void someMethod1(){ //do something before synchronized(anObject) { … } //do something after } public void someMethod2() { //do something before synchronized(anObject) { … } //do something after } Schliessen sich gegenseitig aus, weil beide das selbe Objekt als lock verwenden
Fragen Können statische methoden ( staic ) auch synchronized werden ? –Was wäre das lock object ? Wieso Objekte als locks ? –und nicht z. B. Zahlen, oder Strings ?
Noch mehr Fragen public void addCustomer(DB db, Customer c) { synchronized(db) { addAddress(db, c.Address); db.newCustomer(c); } } public void addAddress(DB database, Address a) { db.verifyAddress(a); synchronized(database) { db.newAddress(db, a); } } Zweimal wird das DB - Objekt als lock verwendet. Funktioniert das ? Wieso ? Wieso nicht ?
4. – ASSIGNMENT 3
Das producer/consumer- Beispiel Der producer produziert ständig neue Werte und schreibt sie in einen gemeinsamen buffer Der consumer liest die Werte aus dem gemeinsamen buffer und verwendet sie Jeder Wert darf nur genau einmal konsumiert werden. Die Frage : Wie synchronisiert man die zwei ? ProducerConsumer Buffer write () read ()