diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/atomicstampedreference/StampedAccount.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/atomicstampedreference/StampedAccount.java new file mode 100644 index 0000000000..1a46e1ba52 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/atomicstampedreference/StampedAccount.java @@ -0,0 +1,34 @@ +package com.baeldung.atomicstampedreference; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicStampedReference; + +public class StampedAccount { + + private AtomicInteger stamp = new AtomicInteger(0); + private AtomicStampedReference account = new AtomicStampedReference<>(0, 0); + + public int getBalance() { + return this.account.get(new int[1]); + } + + public int getStamp() { + int[] stamps = new int[1]; + this.account.get(stamps); + return stamps[0]; + } + + public boolean deposit(int funds) { + int[] stamps = new int[1]; + int current = this.account.get(stamps); + int newStamp = this.stamp.incrementAndGet(); + return this.account.compareAndSet(current, current + funds, stamps[0], newStamp); + } + + public boolean withdrawal(int funds) { + int[] stamps = new int[1]; + int current = this.account.get(stamps); + int newStamp = this.stamp.incrementAndGet(); + return this.account.compareAndSet(current, current - funds, stamps[0], newStamp); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/atomicstampedreference/ThreadStampedAccountUnitTest.java b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/atomicstampedreference/ThreadStampedAccountUnitTest.java new file mode 100644 index 0000000000..ce83355073 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/atomicstampedreference/ThreadStampedAccountUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.atomicstampedreference; + +import org.junit.Assert; +import org.junit.Test; + +public class ThreadStampedAccountUnitTest { + + @Test + public void givenMultiThread_whenStampedAccount_thenSetBalance() throws InterruptedException { + StampedAccount account = new StampedAccount(); + Thread t = new Thread(() -> { + while (!account.withdrawal(100)) + Thread.yield(); + }); + t.start(); + Assert.assertTrue(account.deposit(100)); + t.join(1_000); + Assert.assertFalse(t.isAlive()); + Assert.assertSame(0, account.getBalance()); + } +}