package javacodebook.thread.syncblock1; /** * Kapselt einen int-Wert in einer Klasse. Aus den Wert kann nicht direkt * zugegriffen werden, sonder lediglich über die Methoden get() und set(). */ public class Data { int i=0; public void set(int i) { this.i = i; } public int get() { return i; } } --- Neue Klasse --- package javacodebook.thread.syncblock1; import java.util.Random; /** * Der Thread dient dazu, die Werte in dem Objekt der Klasse Data in * unregelmäßigen Zeitabständen um einen vorgegebenen Wert zu erhöhen. */ class SyncIncThread extends Thread { private static Random random = new Random(System.currentTimeMillis()); private Data data; private int inc; public SyncIncThread(String name, Data data, int inc) { super(name); this.data = data; this.inc = inc; } /** * Der aktuell in dem Objekt data stehende Wert wird 5x in unregelmässigen * zeitlichen Abständen um den Wert inc erhöht. Vor der Durchführung der * Aktion wird versucht, sich auf dem Objekt data zu synchronisieren um zu * verhinden, das mehrere Threads gleichzeitig Daten in dem Objekt * manipulieren können. Auch die 100 ms Schlaf zwischen lesendem und * schreibendem Zugriff ändern daran nichts. */ public void run() { for (int i=0; i<5; i++) { synchronized ( data) { int number = data.get(); System.out.println(getName() + ": Neuer Wert: " + (number+inc)); sleepRandomly(100); data.set(number+inc); } sleepRandomly(1000); } } /** * Legt den Thread für eine zufällige Zeit zwischen 0 und max Millisekunden * schlafen. */ private void sleepRandomly(int max) { try { sleep(random.nextInt(max)); } catch (Exception ignore) {} } } --- Neue Klasse --- package javacodebook.thread.syncblock1; /** * Startet die synchronisierten Threads. Beide Threads erhalten das selbe Objekt * der Klasse Data in das sie jeweils synchronisiert Daten schreiben. */ public class SyncStarter { public static void main(String []args) { Data data = new Data(); Thread inc1 = new SyncIncThread("Anton", data, 1); Thread inc2 = new SyncIncThread("Berta", data, 10); inc1.start(); inc2.start(); } } --- Neue Klasse --- package javacodebook.thread.syncblock1; import java.util.Random; class UnsyncIncThread extends Thread { private static Random random = new Random(System.currentTimeMillis()); private Data data; private int inc; public UnsyncIncThread(String name, Data data, int inc) { super(name); this.data = data; this.inc = inc; } /** * Der aktuell in dem Objekt data stehende Wert wird 5x in unregelmässigen * zeitlichen Abständen um den Wert inc erhöht. Zwischen dem lesenden Zugriff * und dem schreibenden Zugriff wird der Thread für 100 ms schlafen gelegt. * In dieser Zeit können andere Threads Werte in das Objekt data schreiben, * was zu Fehlern in der Berechnung führt. Auch ohne die 100 ms Schlaf * zwischen lesendem und schreibendem Zugriff könnte das passieren. */ public void run() { for (int i=0; i<5; i++) { int number = data.get(); System.out.println(getName() + ": Neuer Wert: " + (number+inc)); sleepRandomly(100); data.set(number+inc); sleepRandomly(1000); } } /** * Legt den Thread für eine zufällige Zeit zwischen 0 und max Millisekunden * schlafen. */ private void sleepRandomly(int max) { try { sleep(random.nextInt(max)); } catch (Exception ignore) {} } } --- Neue Klasse --- package javacodebook.thread.syncblock1; /** * Startet die unsynchronisierten Threads. Beide Threads erhalten das selbe * Objekt der Klasse Data in das sie jeweils unsynchronisiert Daten schreiben. */ public class UnsyncStarter { public static void main(String []args) { Data data = new Data(); Thread inc1 = new UnsyncIncThread("Anton", data, 1); Thread inc2 = new UnsyncIncThread("Berta", data, 10); inc1.start(); inc2.start(); } }