Testing concurrent code question 161 of 180 mid
How do you write a test that actually creates contention?
- Start two threads and hope
- Correct: Start N threads that all block on one barrier, release them together, then join with a timeout and assert the invariant
- Run the same test a thousand times
- Use a single thread and a mock
Threads started in a loop tend to run one after another, because starting a thread takes longer than
the body of a small test. A CyclicBarrier or a CountDownLatch used as a starting gate lines them up
so they collide:
int threads = 8;
var start = new CountDownLatch(1);
var done = new CountDownLatch(threads);
for (int i = 0; i < threads; i++) {
new Thread(() -> {
start.await(); // everyone waits here (try/catch omitted)
for (int n = 0; n < 10_000; n++) counter.increment();
done.countDown();
}).start();
}
start.countDown(); // released together
assertTrue(done.await(10, SECONDS));
assertEquals(threads * 10_000, counter.get());
Then say the caveat, because it is the interesting half: the barrier is itself a memory barrier, so this catches lost updates but hides visibility bugs.
Quiz yourself on Testing concurrent code Suggest a correction