diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java index 0204c31fea..558245283a 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java +++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java @@ -1,34 +1,49 @@ package com.baeldung.abaproblem; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class Account { private AtomicInteger balance = new AtomicInteger(0); + private List transactionDates = new ArrayList<>(); public int getBalance() { return balance.get(); } + public List getTransactionDates() { + return transactionDates; + } + public boolean withdraw(int amount) throws InterruptedException { int current = getBalance(); if (current < amount) { throw new RuntimeException("Not sufficient balance"); } precessBalance(); - return balance.compareAndSet(current, current - amount); + boolean result = balance.compareAndSet(current, current - amount); + if (result) { + transactionDates.add(System.currentTimeMillis()); + } + return result; } private void precessBalance() throws InterruptedException { - if ("thread 1".equals(Thread.currentThread().getName())) { + if ("thread1".equals(Thread.currentThread().getName())) { TimeUnit.SECONDS.sleep(2); } } public boolean deposit(int amount) { int current = balance.get(); - return balance.compareAndSet(current, current + amount); + boolean result = balance.compareAndSet(current, current + amount); + if (result) { + transactionDates.add(System.currentTimeMillis()); + } + return result; } } diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java index ab88a0f447..457580b96c 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,6 +20,7 @@ public class AccountUnitTest { @Test public void zeroBalanceInitializationTest() { assertEquals(0, account.getBalance()); + assertTrue(account.getTransactionDates().isEmpty()); } @Test @@ -55,7 +57,9 @@ public class AccountUnitTest { final int amountToWithdrawByThreadB = 10; final int amountToDepositByThreadB = 10; + assertTrue(account.getTransactionDates().isEmpty()); account.deposit(defaultBalance); + assertEquals(1, account.getTransactionDates().size()); Thread threadA = new Thread(() -> { try { @@ -64,7 +68,7 @@ public class AccountUnitTest { } catch (InterruptedException e) { throw new RuntimeException(e); } - }, "tread 1"); + }, "thread1"); Thread threadB = new Thread(() -> { @@ -80,7 +84,7 @@ public class AccountUnitTest { // thread 1 didn't finish yet, so the original value will be in place for it assertEquals(defaultBalance, account.getBalance()); - }, "thread 2"); + }, "thread2"); threadA.start(); threadB.start(); @@ -89,5 +93,11 @@ public class AccountUnitTest { // compareAndSet operation succeeds for thread 1 assertEquals(defaultBalance - amountToWithdrawByThreadA, account.getBalance()); + + //but there are other transactions + assertNotEquals(2, account.getTransactionDates().size()); + + // thread 2 did two modifications as well + assertEquals(4, account.getTransactionDates().size()); } }