Java

The Java Memory Model (JMM): Volatile, Happens-Before, and Visibility

Master the internals of Java Concurrency. Learn how the Java Memory Model handles instruction reordering, visibility, and the critical 'happens-before' relationship.

Sachin Sarawgi·April 20, 2026·3 min read
#java#concurrency#jmm#multithreading#performance

The Java Memory Model (JMM): The Physics of Java

Writing thread-safe Java code requires more than just adding synchronized to every method. To build truly high-performance concurrent systems, you must understand the Java Memory Model (JMM), which defines how threads interact through memory.

1. The Core Problem: CPU Caches and Reordering

Modern CPUs don't read directly from RAM; they use multiple levels of fast L1/L2/L3 caches.

  • Visibility: If Thread A updates a variable, Thread B might not see that update immediately because it's still reading the old value from its own CPU cache.
  • Reordering: To optimize performance, the Compiler and CPU might change the order of your instructions as long as the result of a single thread remains the same. In multithreaded code, this can be disastrous.

2. The volatile Keyword

The volatile keyword is the simplest way to ensure visibility and prevent reordering.

  • Visibility: Any write to a volatile variable is immediately flushed to main memory. Any read is taken directly from main memory.
  • No Reordering: volatile prevents the compiler from moving code around the variable access (Memory Barriers).
  • Limitation: volatile does not provide atomicity. count++ on a volatile variable is still not thread-safe.

3. The 'Happens-Before' Relationship

The JMM defines a set of rules called "happens-before." If action A happens-before action B, the results of A are guaranteed to be visible to B.

  • Locking: Releasing a lock happens-before acquiring the same lock.
  • Volatile: A write to a volatile variable happens-before every subsequent read of that variable.
  • Thread Start: Calling thread.start() happens-before any action in that thread.
  • Transitivity: If A happens-before B, and B happens-before C, then A happens-before C.

4. Final Fields and Safety

The JMM provides special guarantees for final fields. If an object is "properly constructed" (the this reference doesn't escape during the constructor), then other threads are guaranteed to see the correct values of final fields without any synchronization.

5. Practical Implementation

When should you use what?

  • synchronized / ReentrantLock: Use when you need both visibility and atomicity.
  • volatile: Use for "state flags" (e.g., boolean stopRequested) where you only need visibility.
  • AtomicInteger / AtomicReference: Use for single-variable updates where you need atomicity without the overhead of locks.

Summary

The JMM is the contract between the Java developer and the hardware. By understanding visibility and the happens-before relationship, you can write concurrent code that is not only correct but also highly optimized for modern multi-core processors.

📚

Recommended Resources

Designing Data-Intensive ApplicationsBest Seller

The definitive guide to building scalable, reliable distributed systems by Martin Kleppmann.

View on Amazon
Kafka: The Definitive GuideEditor's Pick

Real-time data and stream processing by Confluent engineers.

View on Amazon
Apache Kafka Series on Udemy

Hands-on Kafka course covering producers, consumers, Kafka Streams, and Connect.

View Course

Practical engineering notes

Get the next backend guide in your inbox

One useful note when a new deep dive is published: system design tradeoffs, Java production lessons, Kafka debugging, database patterns, and AI infrastructure.

No spam. Just practical notes you can use at work.

Sachin Sarawgi

Written by

Sachin Sarawgi

Engineering Manager and backend engineer with 10+ years building distributed systems across fintech, enterprise SaaS, and startups. CodeSprintPro is where I write practical guides on system design, Java, Kafka, databases, AI infrastructure, and production reliability.

Found this useful? Share it: