Skip to content

Commit afbbf0b

Browse files
examples for the blog article Unit Tests for Concurrent Java with VMLens (#18747)
1 parent 92b2b51 commit afbbf0b

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed

libraries-testing-2/pom.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@
190190
<artifactId>javalite-common</artifactId>
191191
<version>${javalite.version}</version>
192192
</dependency>
193+
<dependency>
194+
<groupId>com.vmlens</groupId>
195+
<artifactId>api</artifactId>
196+
<version>${vmlens.version}</version>
197+
<scope>test</scope>
198+
</dependency>
193199
</dependencies>
194200

195201
<build>
@@ -218,6 +224,24 @@
218224
</argLine>
219225
</configuration>
220226
</plugin>
227+
<plugin>
228+
<groupId>com.vmlens</groupId>
229+
<artifactId>vmlens-maven-plugin</artifactId>
230+
<version>${vmlens.version}</version>
231+
<executions>
232+
<execution>
233+
<id>test</id>
234+
<goals>
235+
<goal>test</goal>
236+
</goals>
237+
</execution>
238+
</executions>
239+
<configuration>
240+
<includes>
241+
<include>**/BankAccountTest.java</include>
242+
</includes>
243+
</configuration>
244+
</plugin>
221245
</plugins>
222246
</build>
223247

@@ -238,5 +262,6 @@
238262
<truth.version>0.32</truth.version>
239263
<jgotesting.version>0.12</jgotesting.version>
240264
<javalite.version>1.4.13</javalite.version>
265+
<vmlens.version>1.2.10</vmlens.version>
241266
</properties>
242267
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.baeldung.vmlens;
2+
3+
public class AtomicBankAccount {
4+
5+
private final Object LOCK = new Object();
6+
private volatile int amount;
7+
8+
public int getAmount() {
9+
return amount;
10+
}
11+
12+
public void update(int delta) {
13+
synchronized (LOCK) {
14+
amount += delta;
15+
}
16+
}
17+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.vmlens;
2+
3+
public class RegularFieldBankAccount {
4+
5+
private int amount;
6+
7+
public int getAmount() {
8+
return amount;
9+
}
10+
11+
public void update(int delta) {
12+
amount += delta;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.vmlens;
2+
3+
public class VolatileFieldBankAccount {
4+
5+
private volatile int amount;
6+
7+
public int getAmount() {
8+
return amount;
9+
}
10+
11+
public void update(int delta) {
12+
amount += delta;
13+
}
14+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.baeldung.vmlens;
2+
3+
import static org.hamcrest.CoreMatchers.is;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
import static org.hamcrest.Matchers.anyOf;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import com.vmlens.api.AllInterleavings;
10+
11+
/**
12+
* This test tests the different implementations of a concurrent bank account class.+
13+
* To see what is wrong with RegularFieldBankAccount and VolatileFieldBankAccount replace
14+
* AtomicBankAccount with one of those classes.
15+
*
16+
*/
17+
18+
class BankAccountTest {
19+
20+
@Test
21+
public void whenParallelUpdate_thenAmountSumOfBothUpdates() throws InterruptedException {
22+
try (AllInterleavings allInterleavings = new AllInterleavings("bankAccount.updateUpdate")) {
23+
while (allInterleavings.hasNext()) {
24+
AtomicBankAccount bankAccount = new AtomicBankAccount();
25+
26+
Thread first = new Thread() {
27+
@Override
28+
public void run() {
29+
bankAccount.update(5);
30+
}
31+
};
32+
first.start();
33+
bankAccount.update(10);
34+
first.join();
35+
36+
int amount = bankAccount.getAmount();
37+
assertThat(amount, is(15));
38+
}
39+
}
40+
}
41+
42+
@Test
43+
public void whenParallelUpdateAndGet_thenResultEitherAmountBeforeOrAfterUpdate() throws InterruptedException {
44+
try (AllInterleavings allInterleavings = new AllInterleavings("bankAccount.updateGetAmount")) {
45+
while (allInterleavings.hasNext()) {
46+
AtomicBankAccount bankAccount = new AtomicBankAccount();
47+
48+
Thread first = new Thread() {
49+
@Override
50+
public void run() {
51+
bankAccount.update(5);
52+
}
53+
};
54+
first.start();
55+
56+
int amount = bankAccount.getAmount();
57+
58+
assertThat(amount, anyOf(is(0), is(5)));
59+
first.join();
60+
}
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)