Skip to content

Java Memory Model (JMM)

The Java Memory Model (JMM) is a critical concept in Java concurrency that defines how threads interact through memory and what behaviors are permissible in a multithreaded environment^[600-developer__JMM.md]. It serves as an abstraction layer that shields developers from the complexities of underlying hardware memory architectures, ensuring consistent and predictable behavior across different CPU and operating system platforms^[600-developer__JMM.md].

Key Concepts

Memory Visibility and Atomicity

The JMM primarily addresses the issues of visibility and atomicity. Without a proper memory model, a thread's changes to shared data might not be visible to other threads in a timely manner, leading to stale data reads^[600-developer__JMM.md]. Furthermore, operations that appear atomic in code (like incrementing a variable i++) may not be atomic at the hardware level, causing race conditions^[600-developer__JMM.md].

The Volatile Keyword

A central component in the JMM is the volatile keyword. Unlike regular variables, volatile variables enforce happens-before relationships, ensuring that writes to a volatile variable are immediately visible to all other threads^[600-developer__JMM.md]. The JMM provides specific guarantees for volatile:

  • Visibility: When a thread writes to a volatile variable, all previous writes (to any variable) are flushed to main memory^[600-developer__JMM.md].
  • Ordering: Accesses to volatile variables establish a memory barrier (or fence), preventing the CPU or compiler from reordering instructions across the barrier^[600-developer__JMM.md].

Hardware Level Implementation

The JMM is implemented using hardware-level instructions, specifically memory barriers^[600-developer__JMM.md]. These mechanisms prevent instruction reordering by the CPU and ensure cache coherence between processor cores^[600-developer__JMM.md]。

Synchronization and Locks

In addition to volatile, the JMM defines the memory semantics for locks (intrinsic locks via synchronized). Entering and exiting a synchronized block acts similarly to acquiring and releasing a lock, enforcing happens-before rules that guarantee visibility of changes to other threads that subsequently lock on the same monitor^[600-developer__JMM.md]。

Sources

^[600-developer__JMM.md]