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`.