HuntExams Academy logo
JavaAdvanced#concurrency#jvm

What is the Java Memory Model (JMM)?

Answer

Defines how threads interact through memory: visibility, ordering, happens-before relationships. Provides guarantees for volatile, synchronized, and final fields.

Example

volatile boolean flag = false;
// Thread A: data = 42; flag = true;
// Thread B: if (flag) { read data; } // happens-before guarantees B sees data=42

Detailed explanation

The Java Memory Model (JMM) is the specification that defines which values Java threads may observe when they read shared variables. It governs visibility, ordering, and the guarantees provided by synchronization. It is not the JVM’s heap-and-stack layout or a garbage-collection algorithm. The JMM matters because source-code order alone does not guarantee what another thread observes: compilers, JIT optimizers, and processors can transform execution while preserving the behaviour required by the model.

Its central concept is happens-before, a relationship that establishes visibility and ordering guarantees between actions. Actions earlier in a thread’s program order happen-before later actions in that thread. Releasing a monitor happens-before a subsequent acquisition of the same monitor, and a volatile write happens-before subsequent reads of that same variable. These relationships are transitive, so they can connect ordinary reads and writes across threads. Calling Thread.start() also establishes ordering into the started thread, while successful completion of Thread.join() makes the terminated thread’s actions visible to the joining thread.

Consider an ordinary field data and a volatile boolean flag, initially false. Thread A executes data = 42 followed by flag = true. If Thread B reads flag as true from that write and then reads data, the volatile write/read relationship connects A’s earlier data write to B’s later data read. Assuming no other writes to data, B must see 42. Volatile therefore supports visibility and ordering, but not mutual exclusion: count++ remains a non-atomic read-modify-write operation even when count is volatile. Synchronized provides both monitor-based mutual exclusion and happens-before guarantees.

Final fields have special initialization guarantees: when an object is properly constructed, with no premature escape of this, another thread that obtains its reference can observe its initialized final fields even without ordinary synchronization. This does not make referenced mutable objects permanently thread-safe. Interviewers usually assess whether you can identify the exact synchronization edge, distinguish visibility from atomicity, and explain why elapsed time or apparently correct test runs cannot establish thread safety. Correctly synchronized programs receive the JMM’s sequential-consistency guarantee, allowing reasoning as though thread actions were interleaved in program order.

Key points to remember

  • The JMM specifies legal observations of shared memory, not JVM memory layout.
  • Happens-before relationships are transitive and establish visibility and ordering guarantees.
  • Volatile can publish earlier writes but does not make compound operations atomic.
  • Synchronized provides mutual exclusion and visibility through the same monitor.
  • Final fields have initialization guarantees, not blanket guarantees for later mutation.

Common mistakes candidates make

  • Describing volatile as merely forcing access to main memory instead of explaining its JMM guarantees.
  • Assuming volatile makes count++ atomic or protects invariants involving multiple fields.
  • Treating Thread.sleep(), elapsed time, or passing concurrency tests as proof of happens-before.

Likely follow-up questions

What happens if flag is not volatile?

Without another synchronization mechanism, the example has data races. Thread B is not guaranteed to observe flag becoming true, and observing true does not guarantee that it sees data as 42.

How can you safely implement a shared counter?

Use AtomicInteger.incrementAndGet() for an atomic increment, or protect all counter accesses with the same lock. If the counter participates in an invariant involving other state, locking the entire operation is often appropriate.

Does happens-before mean one operation physically finishes before another?

Happens-before is a specification-level relationship, not simply wall-clock ordering. Implementations may reorder operations internally as long as observable results respect the JMM’s guarantees.

Interview tip: Define the JMM, explain happens-before using the flag example, and finish by distinguishing volatile visibility from synchronized mutual exclusion.

Related Interview Questions

1
JavaAdvanced#spring

Explain Spring Bean lifecycle.

Open
2
JavaIntermediate#spring

What is the difference between Spring Boot and Spring Framework?

Open
3
JavaIntermediate#jpa

What is JPA vs Hibernate?

Open