diff --git a/libraries-testing-2/pom.xml b/libraries-testing-2/pom.xml index f0e9cc19db02..477a40d8ba5f 100644 --- a/libraries-testing-2/pom.xml +++ b/libraries-testing-2/pom.xml @@ -190,6 +190,12 @@ javalite-common ${javalite.version} + + com.vmlens + api + ${vmlens.version} + test + @@ -218,6 +224,24 @@ + + com.vmlens + vmlens-maven-plugin + ${vmlens.version} + + + test + + test + + + + + + **/BankAccountTest.java + + + @@ -238,5 +262,6 @@ 0.32 0.12 1.4.13 + 1.2.10 \ No newline at end of file diff --git a/libraries-testing-2/src/main/java/com/baeldung/vmlens/AtomicBankAccount.java b/libraries-testing-2/src/main/java/com/baeldung/vmlens/AtomicBankAccount.java new file mode 100644 index 000000000000..d8f0037aafb4 --- /dev/null +++ b/libraries-testing-2/src/main/java/com/baeldung/vmlens/AtomicBankAccount.java @@ -0,0 +1,17 @@ +package com.baeldung.vmlens; + +public class AtomicBankAccount { + + private final Object LOCK = new Object(); + private volatile int amount; + + public int getAmount() { + return amount; + } + + public void update(int delta) { + synchronized (LOCK) { + amount += delta; + } + } +} diff --git a/libraries-testing-2/src/main/java/com/baeldung/vmlens/RegularFieldBankAccount.java b/libraries-testing-2/src/main/java/com/baeldung/vmlens/RegularFieldBankAccount.java new file mode 100644 index 000000000000..1f0f546c13ac --- /dev/null +++ b/libraries-testing-2/src/main/java/com/baeldung/vmlens/RegularFieldBankAccount.java @@ -0,0 +1,14 @@ +package com.baeldung.vmlens; + +public class RegularFieldBankAccount { + + private int amount; + + public int getAmount() { + return amount; + } + + public void update(int delta) { + amount += delta; + } +} diff --git a/libraries-testing-2/src/main/java/com/baeldung/vmlens/VolatileFieldBankAccount.java b/libraries-testing-2/src/main/java/com/baeldung/vmlens/VolatileFieldBankAccount.java new file mode 100644 index 000000000000..bb604eb647ad --- /dev/null +++ b/libraries-testing-2/src/main/java/com/baeldung/vmlens/VolatileFieldBankAccount.java @@ -0,0 +1,14 @@ +package com.baeldung.vmlens; + +public class VolatileFieldBankAccount { + + private volatile int amount; + + public int getAmount() { + return amount; + } + + public void update(int delta) { + amount += delta; + } +} diff --git a/libraries-testing-2/src/test/java/com/baeldung/vmlens/BankAccountTest.java b/libraries-testing-2/src/test/java/com/baeldung/vmlens/BankAccountTest.java new file mode 100644 index 000000000000..017a125d0be2 --- /dev/null +++ b/libraries-testing-2/src/test/java/com/baeldung/vmlens/BankAccountTest.java @@ -0,0 +1,63 @@ +package com.baeldung.vmlens; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anyOf; + +import org.junit.jupiter.api.Test; + +import com.vmlens.api.AllInterleavings; + +/** + * This test tests the different implementations of a concurrent bank account class.+ + * To see what is wrong with RegularFieldBankAccount and VolatileFieldBankAccount replace + * AtomicBankAccount with one of those classes. + * + */ + +class BankAccountTest { + + @Test + public void whenParallelUpdate_thenAmountSumOfBothUpdates() throws InterruptedException { + try (AllInterleavings allInterleavings = new AllInterleavings("bankAccount.updateUpdate")) { + while (allInterleavings.hasNext()) { + AtomicBankAccount bankAccount = new AtomicBankAccount(); + + Thread first = new Thread() { + @Override + public void run() { + bankAccount.update(5); + } + }; + first.start(); + bankAccount.update(10); + first.join(); + + int amount = bankAccount.getAmount(); + assertThat(amount, is(15)); + } + } + } + + @Test + public void whenParallelUpdateAndGet_thenResultEitherAmountBeforeOrAfterUpdate() throws InterruptedException { + try (AllInterleavings allInterleavings = new AllInterleavings("bankAccount.updateGetAmount")) { + while (allInterleavings.hasNext()) { + AtomicBankAccount bankAccount = new AtomicBankAccount(); + + Thread first = new Thread() { + @Override + public void run() { + bankAccount.update(5); + } + }; + first.start(); + + int amount = bankAccount.getAmount(); + + assertThat(amount, anyOf(is(0), is(5))); + first.join(); + } + } + } +}