Lesson 12 / 38
The Java Memory Model
Learn the happens-before relation — the only guarantee that one thread sees another's writes — and why unsynchronized code can be reordered by the compiler and CPU.
happens-before
The JMM only guarantees one thread sees another's write if a happens-before edge links them: unlocking then locking the same monitor, writing then reading the same volatile, Thread.start(), Thread.join(), and constructor-to-final-field reads. Without such an edge, the compiler and CPU may reorder freely.
Broken double-checked locking
Without volatile, a reader thread can observe a partially-constructed instance because the JMM allows the constructor write and the field write to be reordered. volatile adds the happens-before edge that fixes it.
class Config {
private static volatile Config instance; // volatile is required
static Config get() {
if (instance == null) {
synchronized (Config.class) {
if (instance == null) instance = new Config();
}
}
return instance;
}
}