Deadlock, livelock and diagnostics question 145 of 180 mid
Why does a debugger so often make a concurrency bug disappear?
- Debuggers fix race conditions
- Correct: A breakpoint, and even a log line, adds synchronisation and delay that changes the interleaving, so the race no longer occurs
- The JIT is disabled under a debugger
- Debuggers run code single threaded
A concurrency bug is a property of one interleaving out of many. Anything that changes timing changes
the distribution of interleavings: a breakpoint suspends threads, a println takes a lock on the
stream and performs I/O, and a logging call flushes buffers. Any of them can make the bad interleaving
effectively impossible.
There is a memory model dimension too. System.out.println is synchronized, so it inserts a happens-
before edge that may be the only reason the values look consistent. Removing a log line and watching a
bug appear is a genuine and maddening experience.
What works instead: stress the code with jcstress, run with -XX:+StressLCM -XX:+StressGCM, test on
weakly ordered hardware (ARM), use assertions and invariant checks rather than prints, and reason about
happens-before rather than about observed behaviour.
Quiz yourself on Deadlock, livelock and diagnostics Suggest a correction