← All articles
Backend1 min read

The Java Memory Model Explained

Why does a value written by one thread sometimes stay invisible to another? The memory model defines the rules, and volatile is often the fix.

S

Swapnika Voora

Author

Each thread can cache values and the compiler can reorder instructions, so a write in one thread is not guaranteed to be seen by another without a synchronization action. The Java Memory Model defines those guarantees.

The visibility problem

Without synchronization, a background thread may loop forever on a stale copy of running because it never re-reads main memory.

Worker.java
private volatile boolean running = true;
 
public void stop() { running = false; }
 
public void run() {
    while (running) {
        process();
    }
}

Happens-before is the contract

volatile writes, lock releases, and thread starts all establish happens-before edges that make prior writes visible to later reads.

Flag.java
// write, then read on another thread — volatile guarantees visibility
config = loaded;      // plain write
ready = true;         // volatile write publishes config safely

Takeaways

  • volatile guarantees visibility and ordering, but not atomicity of compound ops.
  • Use synchronized or java.util.concurrent types for read-modify-write.
  • Reason in terms of happens-before, not intuition about timing.

For counters and flags that need atomic updates, reach for AtomicInteger or AtomicReference rather than volatile alone.

#java#concurrency#memory-model

More in Backend