Last active
March 10, 2024 16:10
-
-
Save rucko24/110f35ef2a16aa74551f61dfa5a07841 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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