Phase 18 of 20 · Topic 18.5

volatile Keyword & Java Memory Model (JMM) Barriers

1Concept

The `volatile` keyword guarantees memory visibility across threads. Without `volatile`, a thread may cache a variable in CPU L1/L2 registers and fail to see updates written by other threads. `volatile` inserts CPU memory barriers, enforcing a happens-before relationship and preventing compiler/CPU instruction reordering.

2Architecture Diagram

[ Thread 1 ] writes volatile flag = true
       |
       v Memory Barrier Flushes L1 Cache
[ Main RAM: flag = true ]
       |
       v Memory Barrier Invalidates L1 Cache
[ Thread 2 ] reads volatile flag = true immediately!

3Code Example

Core Java
public class VolatileVisibilityDemo {
    private static volatile boolean running = true;

    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            long count = 0;
            while (running) { // Reads volatile flag directly from main memory
                count++;
            }
            System.out.println("Worker detected stop signal. Iterations: " + count);
        });

        worker.start();
        Thread.sleep(50);
        running = false; // Writes volatile flag, immediately visible to worker
        System.out.println("Main thread set running = false");
        worker.join();
    }
}

4Expected Output

Main thread set running = false
Worker detected stop signal. Iterations: 54912041

5Key Takeaways

  • `volatile` guarantees visibility and ordering, but does NOT guarantee atomicity (e.g. `count++` is NOT atomic).
  • Use `volatile` for status flags and double-checked locking singletons.
  • For compound atomic operations (increment, compare-and-swap), use `AtomicInteger`.