volatile and visibility

Multithreading · lesson 4 of 38 · 3 min read

Learn why a plain boolean flag can loop forever, and exactly what volatile does and does not fix.

Open this lesson in the learning hub

Key points

  • Threads may keep a field in a register or a CPU cache. Without a memory barrier a writer's change can never reach the reader.
  • volatile means: read and write the real memory location every time, and do not reorder other accesses across it.
  • Perfect for a one-way flag. One thread writes it, any number read it.
  • It does not make count++ safe. That is still read-modify-write, so use an atomic or a lock.
  • volatile also makes long and double access atomic. Without it, a 64-bit value can tear into two halves.

Example

public class Main {
    static volatile boolean running = true;   // remove volatile and this can hang forever
    static long loops = 0;

    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            long local = 0;
            while (running) local++;          // hot loop, no locks
            loops = local;
            System.out.println("worker: saw the flag flip, stopping");
        });
        worker.start();

        Thread.sleep(200);
        running = false;                      // write becomes visible immediately
        worker.join();                        // join also guarantees we see 'loops'

        System.out.println("main  : worker ran " + loops + " iterations");
    }
}

volatile buys visibility, not atomicity.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Multithreading course, and every lesson in it is listed on the Multithreading contents page.