I need to write a unit test that provokes a race condition, so I can check if I can solve the problem later. The problem is that the race condition is very rare, maybe because my computer has only two cores.
The code looks something like this:
class MyDateTime { String getColonTime() { // datetime is some kind of lazy caching variable declared somewhere(does not matter) if (datetime == null) { initDateTime(); //Uses lazy to initlialize variable, takes some time } // Colon time stores hh:mm as string if (datetime.colonTime == null) { StringBuilder sb = new StringBuilder(); //Now do some steps to build the hh:mm string //... //set colon time datetime.colonTime = sb.toString(); } return datetime.colonTime; } }
Explanation: initDateTime assigns a new instance of dateTime, so datetime.colonTime is null after that (since we want to initialize it lazy, as I said). Now, if Thread A enters the method, then the scheduler stops it just before initDateTime () is run. Thread B is now runst getColonTime (), sees that datetime is still null and initializes it. datetime.colonTime is null, so the second if block is executed, and datetime.colonTime is StringBuilder. If then the scheduler stops the thread between this line and the return statement and resumes thread A, the following happens: When A was stopped just before the initDateTime call, A now calls initDateTime (), which will look like reset the datetime object, again setting datetime.colonTime to null . Then thread A will go into the second if block, but the scheduler will abort A before datetime.colonTime = sb.toString (); called. As a conclusion, dateTime.colonTime is still null. Now the scheduler resumes B, and the method returns null.
I tried to provoke a race condition by pointing multiple threads calling getColonTime () on one (final) instance of MyDateTime, but it only fails in some unusually rare cases :( Any hints on how to write JUnit "test"?
source share