The Java Memory Model (JMM) is the specification that defines how threads interact with shared memory, including when a write by one thread becomes visible to another and what reorderings of operations are legal. It exists because modern CPUs and compilers reorder and cache memory operations for performance, and without rules, concurrent code would behave unpredictably.
Key Points: • The JMM defines happens-before relationships, a formal ordering that guarantees when one thread's memory writes are guaranteed visible to another thread's reads. • Each thread may keep variables in CPU registers or local caches instead of main memory; without synchronization, another thread can see stale values indefinitely. • The volatile keyword establishes a happens-before edge for that specific variable, forcing reads and writes to go through main memory and preventing certain reorderings. • synchronized blocks establish happens-before between a lock's release and the next thread's acquisition of that same lock, making all prior writes visible. • The JMM also governs atomicity, such as 64-bit long or double writes not being guaranteed atomic without volatile, and prevents specific harmful instruction reorderings around synchronization points.
Example: Without volatile or synchronization, a flag set to true by a worker thread might never be observed by a monitoring thread, because the monitoring thread keeps reading a cached copy of the flag, a classic visibility bug the JMM's rules are designed to prevent.
Interview Tip: A concise interview answer is:
"The Java Memory Model specifies the rules for how and when memory writes made by one thread become visible to other threads, using the concept of happens-before relationships. Constructs like volatile, synchronized, and java.util.concurrent utilities are how you establish those guarantees, which is why unsynchronized shared mutable state is unsafe even if it looks fine in a single-threaded test."