Java Concurrency Interview

The Java memory model question 16 of 180 senior

Why does double-checked locking need the field to be volatile?

instance = new Helper() is three steps: allocate, run the constructor, publish the reference. The JIT is allowed to publish before the constructor finishes, because within the constructing thread nothing can tell the difference. Another thread taking the fast path sees a non-null reference and reads fields that are still at their defaults.

volatile forbids that reordering and gives the reader the acquire edge that makes the constructor's writes visible. This was genuinely broken before Java 5, which is why the "broken DCL" folklore still circulates.

private static volatile Helper instance;   // volatile is the whole fix

static Helper get() {
    Helper local = instance;               // one volatile read on the fast path
    if (local == null) {
        synchronized (Helper.class) {
            local = instance;
            if (local == null) {
                instance = local = new Helper();
            }
        }
    }
    return local;
}

For a static singleton, the holder idiom is simpler and needs no volatile at all: class initialisation is already synchronised by the JVM.

memory-model volatile singleton

Quiz yourself on The Java memory model Suggest a correction