volatile

volatile is a field modifier that guarantees writes to the field are immediately visible to all threads. It prevents the JVM and CPU from caching the value in a register or local cache. It provides visibility but not atomicity.

Example

public class StopFlag {
    private volatile boolean stop = false;

    public void stop() { stop = true; }

    public void run() {
        while (!stop) {
            // do work
        }
    }
}

Without volatile, a worker thread might cache stop in a register and never see the update from another thread.

volatile vs synchronized vs atomic

  • volatile β€” visibility only. Reads and writes are atomic for primitive types (except long/double on 32-bit JVMs β€” but that's rare today). No atomicity for compound operations like i++.
  • synchronized β€” visibility + mutual exclusion + atomicity for the whole block.
  • Atomic classes (AtomicInteger) β€” visibility + atomic compound operations (incrementAndGet).

When to use volatile

  • One thread writes, many threads read (flags, latest-value variables).
  • Double-checked locking singletons (with an appropriately-typed field).
  • Counters used by a single writer.

For most counters with multiple writers, prefer AtomicInteger over volatile int + synchronized.