Concurrency
concurrency2SynchronizationDemo
- Path
- pkg7concurrency/concurrency2SynchronizationDemo.java
- Package
- pkg7concurrency
- Study order
- 2
- Run
- Single-file source launch
- Command
- java pkg7concurrency/concurrency2SynchronizationDemo.java
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg7concurrency;2 3/*4 * concurrency2SynchronizationDemo.java5 * ------------------------6 * Demonstrates a RACE CONDITION and three fixes: synchronized, AtomicInteger,7 * and a lock. Also shows why `volatile` alone is NOT enough for count++.8 *9 * RACE CONDITION: count++ is read-modify-write (3 steps); concurrent threads10 * interleave and lose updates.11 */12import java.util.concurrent.atomic.AtomicInteger;13import java.util.concurrent.locks.*;14 15public class concurrency2SynchronizationDemo {16 17 static int unsafe = 0; // racy18 static int guarded = 0; // protected by `lock`19 static final AtomicInteger atomic = new AtomicInteger();20 static final Object monitor = new Object();21 static final ReentrantLock lock = new ReentrantLock();22 static int synced = 0;23 24 static void incUnsafe() { unsafe++; }25 static void incSynced() { synchronized (monitor) { synced++; } }26 static void incLocked() { lock.lock(); try { guarded++; } finally { lock.unlock(); } }27 28 public static void main(String[] args) throws InterruptedException {29 final int THREADS = 8, PER = 50_000, EXPECTED = THREADS * PER;30 31 run("unsafe (race)", THREADS, PER, concurrency2SynchronizationDemo::incUnsafe);32 run("synchronized", THREADS, PER, concurrency2SynchronizationDemo::incSynced);33 run("ReentrantLock", THREADS, PER, concurrency2SynchronizationDemo::incLocked);34 run("AtomicInteger", THREADS, PER, atomic::incrementAndGet);35 36 System.out.println("\nEXPECTED = " + EXPECTED);37 System.out.println("unsafe = " + unsafe + " <- usually LESS (lost updates)");38 System.out.println("synchronized = " + synced);39 System.out.println("ReentrantLock = " + guarded);40 System.out.println("AtomicInteger = " + atomic.get());41 }42 43 static void run(String label, int threads, int per, Runnable inc) throws InterruptedException {44 Thread[] ts = new Thread[threads];45 for (int i = 0; i < threads; i++) {46 ts[i] = new Thread(() -> { for (int j = 0; j < per; j++) inc.run(); });47 ts[i].start();48 }49 for (Thread t : ts) t.join();50 }51}