added transaction recording
This commit is contained in:
parent
a6fc46e3f6
commit
68dc88528e
|
@ -1,34 +1,49 @@
|
||||||
package com.baeldung.abaproblem;
|
package com.baeldung.abaproblem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class Account {
|
public class Account {
|
||||||
|
|
||||||
private AtomicInteger balance = new AtomicInteger(0);
|
private AtomicInteger balance = new AtomicInteger(0);
|
||||||
|
private List<Long> transactionDates = new ArrayList<>();
|
||||||
|
|
||||||
public int getBalance() {
|
public int getBalance() {
|
||||||
return balance.get();
|
return balance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Long> getTransactionDates() {
|
||||||
|
return transactionDates;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean withdraw(int amount) throws InterruptedException {
|
public boolean withdraw(int amount) throws InterruptedException {
|
||||||
int current = getBalance();
|
int current = getBalance();
|
||||||
if (current < amount) {
|
if (current < amount) {
|
||||||
throw new RuntimeException("Not sufficient balance");
|
throw new RuntimeException("Not sufficient balance");
|
||||||
}
|
}
|
||||||
precessBalance();
|
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 {
|
private void precessBalance() throws InterruptedException {
|
||||||
if ("thread 1".equals(Thread.currentThread().getName())) {
|
if ("thread1".equals(Thread.currentThread().getName())) {
|
||||||
TimeUnit.SECONDS.sleep(2);
|
TimeUnit.SECONDS.sleep(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean deposit(int amount) {
|
public boolean deposit(int amount) {
|
||||||
int current = balance.get();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ public class AccountUnitTest {
|
||||||
@Test
|
@Test
|
||||||
public void zeroBalanceInitializationTest() {
|
public void zeroBalanceInitializationTest() {
|
||||||
assertEquals(0, account.getBalance());
|
assertEquals(0, account.getBalance());
|
||||||
|
assertTrue(account.getTransactionDates().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -55,7 +57,9 @@ public class AccountUnitTest {
|
||||||
final int amountToWithdrawByThreadB = 10;
|
final int amountToWithdrawByThreadB = 10;
|
||||||
final int amountToDepositByThreadB = 10;
|
final int amountToDepositByThreadB = 10;
|
||||||
|
|
||||||
|
assertTrue(account.getTransactionDates().isEmpty());
|
||||||
account.deposit(defaultBalance);
|
account.deposit(defaultBalance);
|
||||||
|
assertEquals(1, account.getTransactionDates().size());
|
||||||
|
|
||||||
Thread threadA = new Thread(() -> {
|
Thread threadA = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
|
@ -64,7 +68,7 @@ public class AccountUnitTest {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}, "tread 1");
|
}, "thread1");
|
||||||
|
|
||||||
Thread threadB = new Thread(() -> {
|
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
|
// thread 1 didn't finish yet, so the original value will be in place for it
|
||||||
assertEquals(defaultBalance, account.getBalance());
|
assertEquals(defaultBalance, account.getBalance());
|
||||||
|
|
||||||
}, "thread 2");
|
}, "thread2");
|
||||||
|
|
||||||
threadA.start();
|
threadA.start();
|
||||||
threadB.start();
|
threadB.start();
|
||||||
|
@ -89,5 +93,11 @@ public class AccountUnitTest {
|
||||||
|
|
||||||
// compareAndSet operation succeeds for thread 1
|
// compareAndSet operation succeeds for thread 1
|
||||||
assertEquals(defaultBalance - amountToWithdrawByThreadA, account.getBalance());
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue