diff --git a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/atomic/SafeAccount.java b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/atomic/SafeAccount.java new file mode 100644 index 0000000000..febfd481c3 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/atomic/SafeAccount.java @@ -0,0 +1,34 @@ +package com.baeldung.concurrent.atomic; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicStampedReference; + +public class SafeAccount { + + AtomicInteger stamp = new AtomicInteger(0); + AtomicStampedReference balance = new AtomicStampedReference<>(0, 0); + + public int getBalance() { + return this.balance.get(new int[1]); + } + + public int getStamp() { + int[] stamps = new int[1]; + this.balance.get(stamps); + return stamps[0]; + } + + public boolean deposit(int funds) { + int[] stamps = new int[1]; + int current = this.balance.get(stamps); + int newStamp = this.stamp.incrementAndGet(); + return this.balance.compareAndSet(current, current + funds, stamps[0], newStamp); + } + + public boolean withdrawal(int funds) { + int[] stamps = new int[1]; + int current = this.balance.get(stamps); + int newStamp = this.stamp.incrementAndGet(); + return this.balance.compareAndSet(current, current - funds, stamps[0], newStamp); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/atomic/ThreadSafeAccountTest.java b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/atomic/ThreadSafeAccountTest.java new file mode 100644 index 0000000000..b9a5fe7773 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/atomic/ThreadSafeAccountTest.java @@ -0,0 +1,21 @@ +package com.baeldung.concurrent.atomic; + +import org.junit.Assert; +import org.junit.Test; + +public class ThreadSafeAccountTest { + + @Test + public void givenMultiThread_whenSafeAccountSetBalance() throws InterruptedException { + SafeAccount account = new SafeAccount(); + 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()); + } +}