import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; public class Counter { // Esempio 3 boolean printed = false; // Esempio 4 Boolean printedObj = false; // Pericoloso, di solito si usa un oggetto final (non applicabile in questo caso) // Esempio 5 AtomicBoolean printedAtomic = new AtomicBoolean(false); // Esempio 1: Non sincronizzato public void count(int number) { for (int i=0; i < 10; ++i) { System.out.println("Thread " + Thread.currentThread().getName() + " count: " + i*number); try { Thread.sleep(200); } catch (InterruptedException e) { throw new RuntimeException(e); } } } // Esempio 2 public synchronized void countSync(int number) { for (int i=0; i < 10; ++i) { System.out.println("Thread " + Thread.currentThread().getName() + " count: " + i*number); try { Thread.sleep(200); } catch (InterruptedException e) { throw new RuntimeException(e); } } } // Esempio 3 public void synchronizedBlock() { int randomNumber = new Random().nextInt(); synchronized(this) { if (!printed) { System.out.println("Thread " + Thread.currentThread().getName() + " random count: " + randomNumber); printed = true; } } } // Esempio 4 public void synchronizedBlockBoolean() { int randomNumber = new Random().nextInt(); synchronized(printedObj) { if (!printedObj) { System.out.println("Thread " + Thread.currentThread().getName() + " random count: " + randomNumber); printedObj = true; } } } // Esempio 5 public void synchronizedAtomic() { int randomNumber = new Random().nextInt(); // Attenzione, solo la specifica operazione è atomica, non c'è attesa sul blocco if (!printedAtomic.getAndSet(true)) { System.out.println("Thread " + Thread.currentThread().getName() + " random count: " + randomNumber); } } // Esempio 6 public static synchronized void staticCount(int number) { for (int i=0; i < 10; ++i) { System.out.println("Thread " + Thread.currentThread().getName() + " count: " + i*number); try { Thread.sleep(200); } catch (InterruptedException e) { throw new RuntimeException(e); } } } // Esempio 7 public static void staticInnerSyncCount(int number) { synchronized (Counter.class) { for (int i = 0; i < 10; ++i) { System.out.println("Thread " + Thread.currentThread().getName() + " count: " + i * number); try { Thread.sleep(200); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } }