I’m looking into a potential concurrency issue in some binary Java code. The code sometimes has a strange behavior, but I’m not sure if it’s actually due to concurrency issues in the code itself, or if it’s something else. I haven’t been able to reproduce the strange behavior myself, but only seen it happening in our log files.
Is there a way to up the context switch frequency of the JVM, in order to surface potential concurrency issues with higher probability? Preferably doing this without explicitly inserting calls to Thread::yeild or Thread::sleep in the code.
Advertisement
Answer
I think the Thread-weaver test framework can help you. It’s been a while since I’ve experimented with it, but it does allow you to force a particular scheduling. It can also be run in a sort of default mode where a lot of interleavings between two methods are tested.
This is a simple example test (using default interleaving)
public class MyListTest { private MyList<String> list; @Test public void testThreading() { AnnotatedTestRunner runner = new AnnotatedTestRunner(); // Run all Weaver tests in this class, using MyList as the Class Under Test. runner.runTests(this.getClass(), MyList.class); } @ThreadedBefore public void before() { list = new MyList<>(); } @ThreadedMain public void mainThread() { list.putIfAbsent("A"); } @ThreadedSecondary public void secondThread() { list.putIfAbsent("A"); } @ThreadedAfter public void after() { assertThat(list).hasSize(1); } }