Detecting Java Race Conditions With Tests, Part 2

July 27, 2016

If you update a field from different threads, you must make sure that between the read and the write from one thread the field is not updated by another thread. You can achieve this by using a synchronized block or the atomic compareAndSet method. But how can you test it?

Example of a Test

Let us look at an example of an incorrect synchronized class:
class Account {
	private int amount = 0;
	public synchronized int getAmount() {
		return amount;
	}
	public synchronized void setAmount(int amount) {
		this.amount = amount;
	}
}
To test this class we use the following junit test case:
@RunWith(ConcurrentTestRunner.class)
public class TestAccount {
	private final Account account = new Account();
    private final static int THREAD_COUNT = 2;
	@Test
	@ThreadCount(THREAD_COUNT)
	public void testAdd() {
		account.setAmount(  account.getAmount() + 20  );
	}
	@After
	public void chechBalance()
	{
		assertEquals( "" , THREAD_COUNT * 20 , account.getAmount()  ); 
	}
}
This junit test uses concurrent-junit to run the test in parallel. The test sometimes succeed, sometimes fails. Every time the get method is called immediately one after the other the sum is incorrect. In the vmlens Method Explorer you can see the order of the two methods. In case of an error you will see the following:

Java Race Condition Non Atomic Update

The Solution: Waitpoints

For a test this is rather inconvenient. If a test fails, which is bad enough, it should at least always fail. To achieve this, a thread needs to wait for the other threads before calling the set method. In vmlens this can be done by using a “waitpoint”. You can set waitepoints at the beginning of a monitor block or a volatile field access: If we set the waitepoint at the synchronized block of the set method the test always fails:

vmlens Waitpoint

Conclusion

In the first part you have seen how to detect lost updates with tests. This second part shows how to detect non atomic updates. In the next part we will see, how to use this technique to test for thread safety. If you have any questions or remarks please comment below.

testing multi-threaded applications on the JVM made easy

LEARN MORE

© 2020 vmlens Legal Notice Privacy Policy