volatile vs synchronized — when does volatile suffice? — Cracked Java
// Concurrency & Multithreading · Java Memory Model, volatile & happens-before
MidTheoryTrick

volatile vs synchronized — when does volatile suffice?

Both establish happens-before, so both fix visibility and ordering. The difference is atomicity and scope: synchronized provides mutual exclusion over a region of code (any number of fields, compound actions), while volatile only governs a single field and provides no mutual exclusion. Use volatile when a single thread writes and others read, with no read-modify-write.

When volatile suffices

volatile is enough when the write does not depend on the current value and you only need fresh single-field reads. The canonical cases:

  • A status flag flipped once: volatile boolean shutdown; — one writer flips it, many readers poll it.
  • Safe publication of an already-built value: volatile Config config; — assign a fully-constructed immutable object, readers see it whole (via the volatile happens-before edge).
class Worker implements Runnable {
    private volatile boolean running = true;   // visibility is all we need
    public void run() {
        while (running) { doWork(); }          // sees the flip promptly
    }
    public void stop() { running = false; }    // simple assignment, not compound
}

When you need synchronized (or locks/atomics)

The moment you have a compound action — read-modify-write or check-then-act — volatile is insufficient because it doesn't make the sequence atomic.

volatile int count;
void inc() { count++; }      // BROKEN: lost updates

synchronized void incSafe() { count++; }  // atomic + visible

You also need a lock when an invariant spans multiple fields that must change together (e.g. low <= high); volatile can only make each field individually visible, not keep them mutually consistent.

OperationBestAverageWorstNote
Mutual exclusionnovolatileyes (synchronized)only synchronized blocks other threads
Visibilityyesbothyesboth create happens-before
Compound atomicitynovolatileyes (synchronized)volatile can't make i++ atomic
Blocking / context switchnonevolatilepossible (synchronized)volatile never blocks
Scopeone fieldvolatilecode region (synchronized)lock guards many fields

Mark your status