Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rucko24/110f35ef2a16aa74551f61dfa5a07841 to your computer and use it in GitHub Desktop.
Save rucko24/110f35ef2a16aa74551f61dfa5a07841 to your computer and use it in GitHub Desktop.
package org.example.example6DataRace.anotherexample;
import org.example.bankaccount.BankAccount;
import org.example.bankaccount.BankAccountWithStampedLock;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import java.util.concurrent.Executors;
import static org.junit.jupiter.api.Assertions.assertEquals;
interface ShowData {
default <T> void info(T t) {
System.out.println(Thread.currentThread().getName() + " " + t);
}
static <T> void sInfo(final T t) {
System.out.println(Thread.currentThread().getName() + " " + t);
}
}
class ProcessBackAccountWithStampedLockTest implements ShowData {
private static final int CORES = Runtime.getRuntime().availableProcessors();
@RepeatedTest(1000)
@DisplayName("Using StampedLock with the bankAccount in it")
void bankAccountWithStampedLock() {
final BankAccountWithStampedLock bankAccountWithStampedLock = new BankAccountWithStampedLock(new BankAccount());
bankAccountWithStampedLock.deposit(1000);
int iterations = 100;
try (var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
bankAccountWithStampedLock.withdraw(1);
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
bankAccountWithStampedLock.deposit(1);
info("Thead name " + Thread.currentThread().getName());
}
});
}
try (var executor2 = Executors.newFixedThreadPool(CORES)) {
executor2.submit(() -> {
for (int i = 0; i < iterations; i++) {
var accountResult = bankAccountWithStampedLock.tryOptimisticRead(bankAccountWithStampedLock::getBalance, () -> bankAccountWithStampedLock);
assertEquals(accountResult.getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
executor2.submit(() -> {
for (int i = 0; i < iterations; i++) {
var accountResult = bankAccountWithStampedLock.tryOptimisticRead(bankAccountWithStampedLock::getBalance, () -> bankAccountWithStampedLock);
assertEquals(accountResult.getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
}
assertEquals(bankAccountWithStampedLock.getBalance(), 1000);
}
@RepeatedTest(1000)
@DisplayName("Test usando BackAccount mutable, debe de fallar la asercion un par de veces")
void testBackAccountMutable() {
BankAccount account = new BankAccount();
account.deposit(1000);
int iterations = 100;
try (var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.withdraw(1);
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.deposit(1);
info("Thead name " + Thread.currentThread().getName());
}
});
}
try (var executor2 = Executors.newFixedThreadPool(CORES)) {
executor2.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertEquals(account.getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
executor2.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertEquals(account.getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
}
assertEquals(account.getBalance(), 1000);
}
@RepeatedTest(1000)
@DisplayName("Test usando BackAccount mutable sin CAS pero con AtomicReference")
void testBackAccountMutableSinCas() {
AtomicReference<BankAccount> account = new AtomicReference<>(new BankAccount());
account.get().deposit(1000);
int iterations = 500;
try(var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.get().withdraw(1);
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.get().deposit(1);
info("Thead name " + Thread.currentThread().getName());
}
});
}
try (var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertEquals(account.get().getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertEquals(account.get().getBalance(), 1000);
info("Thead name " + Thread.currentThread().getName());
}
});
}
assertEquals(account.get().getBalance(), 1000);
}
@RepeatedTest(1000)
@DisplayName("AtomicReference with BankAccount object")
void testConAtomicReference() {
BankAccountWithAtomicReference account = new BankAccountWithAtomicReference();
account.deposit(1000);
int iterations = 500;
try (var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.withdraw(1);
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
account.deposit(1);
info("Thead name " + Thread.currentThread().getName());
}
});
}
try (var executor = Executors.newFixedThreadPool(CORES)) {
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertAll(() -> assertEquals(account.getBalance(), 1000));
info("Thead name " + Thread.currentThread().getName());
}
});
executor.submit(() -> {
for (int i = 0; i < iterations; i++) {
assertAll(() -> assertEquals(account.getBalance(), 1000));
info("Thead name " + Thread.currentThread().getName());
}
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment