Happens-before, precisely
advanced17 min readLesson 129 of 180
The five hb edges, the broken stop-flag, and why visibility fails without them.
The Java Memory Model (JLS ยง17.4) defines happens-before โ the only arrow that matters when threads share data. If action A happens-before B, B sees A's effects. Without that edge, visibility is not guaranteed: a plain boolean written by another thread may never be seen by your loop.
Three hb edges you can build on:
- Program order within one thread.
- Monitor rules: unlock happens-before every later lock of the same
monitor; every method of a
java.util.concurrentlock does the same. - Volatile: a write to a volatile field happens-before every later read of that field.
And two structural edges you get for free:
- Thread.start() happens-before anything the new thread does.
- Everything a thread does happens-before join() detects its exit.
The classic broken pattern โ a busy flag:
class Stop {
private static boolean run = true; // NOT volatile
static void stop() { run = false; } // may never be visible
static void loop() { while (run) {} } // may spin forever
}
This is not pedantry: JIT-tier compilers may hoist the read out of the loop because nothing in the model forces them to re-read.