[JAVA-9986] Fix ThreadStamped unit test

This commit is contained in:
Haroon Khan 2022-02-17 08:29:23 +00:00
parent c4065e80b4
commit cd70006bb6
2 changed files with 45 additions and 16 deletions

View File

@ -1,25 +1,22 @@
package com.baeldung.atomicstampedreference; package com.baeldung.atomicstampedreference;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference; import java.util.concurrent.atomic.AtomicStampedReference;
public class StampedAccount { public class StampedAccount {
private AtomicInteger stamp = new AtomicInteger(0); private final AtomicInteger stamp = new AtomicInteger(0);
private AtomicStampedReference<Integer> account = new AtomicStampedReference<>(0, 0); private final AtomicStampedReference<Integer> account = new AtomicStampedReference<>(0, 0);
public int getBalance() {
return account.getReference();
}
public int getStamp() {
return account.getStamp();
}
public boolean deposit(int funds) { public boolean deposit(int funds) {
int[] stamps = new int[1]; int[] stamps = new int[1];
int current = this.account.get(stamps); int current = this.account.get(stamps);
int newStamp = this.stamp.incrementAndGet(); int newStamp = this.stamp.incrementAndGet();
// Thread is paused here to allow other threads to update the stamp and amount (for testing only)
sleep();
return this.account.compareAndSet(current, current + funds, stamps[0], newStamp); return this.account.compareAndSet(current, current + funds, stamps[0], newStamp);
} }
@ -29,4 +26,19 @@ public class StampedAccount {
int newStamp = this.stamp.incrementAndGet(); int newStamp = this.stamp.incrementAndGet();
return this.account.compareAndSet(current, current - funds, stamps[0], newStamp); return this.account.compareAndSet(current, current - funds, stamps[0], newStamp);
} }
public int getBalance() {
return account.getReference();
}
public int getStamp() {
return account.getStamp();
}
private static void sleep() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
}
}
} }

View File

@ -1,21 +1,38 @@
package com.baeldung.atomicstampedreference; package com.baeldung.atomicstampedreference;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class ThreadStampedAccountUnitTest { public class ThreadStampedAccountUnitTest {
@Test @Test
public void givenMultiThread_whenStampedAccount_thenSetBalance() throws InterruptedException { public void givenMultiThread_whenStampedAccount_thenSetBalance() throws InterruptedException {
StampedAccount account = new StampedAccount(); StampedAccount account = new StampedAccount();
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
while (!account.withdrawal(100)) while (!account.deposit(100)) {
Thread.yield(); Thread.yield();
}
}); });
t.start(); t.start();
Assert.assertTrue(account.deposit(100));
t.join(1_000); Thread t2 = new Thread(() -> {
Assert.assertFalse(t.isAlive()); while (!account.withdrawal(100)) {
Assert.assertSame(0, account.getBalance()); Thread.yield();
}
});
t2.start();
t.join(10_000);
t2.join(10_000);
assertFalse(t.isAlive());
assertFalse(t2.isAlive());
assertEquals(0, account.getBalance());
assertTrue(account.getStamp() > 0);
} }
} }