From d9d276b0c986f332c1bc04a0c67867f4db59ba0a Mon Sep 17 00:00:00 2001 From: Luca Conte Date: Wed, 23 Apr 2025 23:10:23 +0200 Subject: [PATCH] u06-4 --- u06-4/AtomicCounter.java | 22 ++++++++++++++++++++++ u06-4/AtomicCounterTest.java | 30 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 u06-4/AtomicCounter.java create mode 100644 u06-4/AtomicCounterTest.java diff --git a/u06-4/AtomicCounter.java b/u06-4/AtomicCounter.java new file mode 100644 index 0000000..76fbe3c --- /dev/null +++ b/u06-4/AtomicCounter.java @@ -0,0 +1,22 @@ +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.IntUnaryOperator; + +class AtomicCounter { + private AtomicInteger i; + + public AtomicCounter() { + this.i = new AtomicInteger(0); + }; + + public int updateAndGet(IntUnaryOperator op) { + // not safe if op is not a pure function + + int oldVal; + + do { + oldVal = i.get(); + } while (!i.compareAndSet(oldVal, op.applyAsInt(oldVal))); + + return op.applyAsInt(oldVal); + } +} \ No newline at end of file diff --git a/u06-4/AtomicCounterTest.java b/u06-4/AtomicCounterTest.java new file mode 100644 index 0000000..dfdda84 --- /dev/null +++ b/u06-4/AtomicCounterTest.java @@ -0,0 +1,30 @@ +public class AtomicCounterTest { + private static final int N_THREADS = 100; + private static final int INCREMENT = 1_000_000; + private static void incCounter(AtomicCounter atomicCounter) { + for (int i= 0; i < INCREMENT; ++i) { + atomicCounter.updateAndGet(x -> x+1); + } + } + public static void main(String[] args) { + AtomicCounter atomicCounter = new AtomicCounter(); + Thread[] threads = new Thread[N_THREADS]; + for (int i = 0; i < N_THREADS; ++i) { + Thread incrementer = new Thread(()-> incCounter(atomicCounter)); + incrementer.start(); + threads[i] = incrementer; + } + for (Thread incrementer: threads) { + try { + incrementer.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("Counter value = " + + atomicCounter.updateAndGet(x -> x) + // only to get, not to change + " and that is" + + (atomicCounter.updateAndGet(x -> x) == N_THREADS * INCREMENT ? "" : "NOT") + + " correct."); + } +}