Java memory model quiz (15 questions)
June 5, 2026
- Java
- JVM
- Concurrency
- Backend
This set goes past API memorization and into the reasoning interviewers use to separate surface-level concurrency knowledge from real understanding. The key theme is not just which keyword to choose, but what visibility and ordering guarantee that choice creates.
If these questions still feel slippery, practice drawing the write-read relationships explicitly. Once you can explain the happens-before edge in plain language, most memory model interview questions become much easier to defend out loud.
Question 1
One thread sets ready = true and another spins until ready becomes true. Without synchronization or volatile, what is the safest assumption?
Reveal answer
Answer
The reader may never observe the update - The safest assumption is that the reader may never observe the update in a timely way, or at all from the program's point of view.
Explanation
Without a happens-before relationship, the Java Memory Model does not guarantee visibility of one thread's write to another thread's read. CPU caches, compiler optimizations, and instruction reordering can all contribute to stale observations.
Common interview notes
A classic follow-up is how declaring ready as volatile changes the guarantee.
Question 2
What does a happens-before relationship primarily guarantee?
Reveal answer
Answer
Earlier writes become visible to a later read that is ordered after them - A happens-before relationship guarantees visibility and ordering for memory effects between the related actions.
Explanation
If action A happens-before action B, then the writes visible at A are guaranteed to be visible to B, subject to the normal rules of the memory model. This is why synchronization, volatile, thread start, thread join, and final-field rules matter.
Common interview notes
Good answers mention that happens-before is broader than locking alone and includes several language-level ordering edges.
Question 3
Which statement about volatile is correct?
Reveal answer
Answer
It provides visibility and ordering guarantees for reads and writes of that variable - volatile provides visibility and certain ordering guarantees for reads and writes of that variable.
Explanation
A volatile write is visible to later volatile reads of the same variable, and the memory model prevents some reorderings around those accesses. It does not make compound actions such as increment atomic, and it does not replace mutual exclusion for larger critical sections.
Common interview notes
Interviewers often ask you to compare volatile with synchronized and atomic classes in one concrete scenario.
Question 4
Why can instruction reordering be legal in correctly synchronized Java programs?
Reveal answer
Answer
Because the JVM may reorder operations as long as single-thread semantics and memory model guarantees are preserved - Reordering can be legal as long as the observable behavior remains valid under the Java Memory Model.
Explanation
Compilers and processors may change execution order for performance if the resulting program still respects the guarantees required by synchronization, volatile, final-field semantics, and as-if-serial behavior for a single thread. Unsafely shared state is where those optimizations become visible as bugs.
Common interview notes
A strong answer separates source order, execution order, and visibility order instead of treating them as identical.
Question 5
You publish an immutable configuration object through a properly constructed final field reference. Why is that attractive for concurrency?
Reveal answer
Answer
final fields have special visibility guarantees after safe construction - final fields have special visibility guarantees once the object is constructed safely and then published.
Explanation
The memory model gives stronger guarantees for final fields than for ordinary mutable fields, which is one reason immutable objects are so useful in concurrent code. However, the object still must not leak this during construction, and referenced mutable state can still be a problem.
Common interview notes
Follow-ups often ask whether final on a reference also makes the referenced object immutable. It does not.
Question 6
After threadA calls threadB.start, which statement is true?
Reveal answer
Answer
Actions in threadA before start happen-before actions in threadB after it begins - Actions in the parent thread before start happen-before actions in the started thread after it begins.
Explanation
Thread start creates an ordering edge in the Java Memory Model. That is why state prepared before calling start can be safely observed by the new thread without extra publication steps, assuming the object graph itself is not being mutated unsafely later.
Common interview notes
The symmetric follow-up is usually about what join guarantees on the way back.
Question 7
What does threadA.join on threadB give threadA after join returns successfully?
Reveal answer
Answer
It guarantees threadA can see the effects of threadB's completed actions - join establishes that threadA can observe the memory effects of threadB's completed actions after the join returns.
Explanation
Thread completion and successful join form another happens-before edge. This is why join is not only a coordination tool for waiting, but also a visibility tool for results written before the worker thread finished.
Common interview notes
A strong answer connects join to both liveness and visibility instead of treating it as mere blocking.
Question 8
Which pattern is unsafe without volatile or synchronization in a lazily initialized singleton?
Reveal answer
Answer
Double-checked locking with a non-volatile instance field - Double-checked locking is unsafe when the instance field is not volatile.
Explanation
Without volatile, another thread can observe a reference to a partially constructed object due to reordering between allocation, assignment, and initialization. Modern Java supports double-checked locking only when the shared instance reference is volatile.
Example
class Holder {
private static volatile Holder instance;
} Common interview notes
This is a classic senior-level question. Interviewers usually want you to explain partial construction, not just recite the rule.
Question 9
Why is publishing this from a constructor considered dangerous?
Reveal answer
Answer
Other threads can observe the object before construction has finished - Publishing this from a constructor is dangerous because another thread may observe the object before initialization is complete.
Explanation
Escaping this during construction breaks the assumptions behind safe initialization and final-field semantics. Listeners, thread starts, and callbacks registered from constructors are common ways this bug appears in practice.
Common interview notes
A good answer names at least one real escape path, such as starting a thread in the constructor or registering a listener.
Question 10
Which statement about reading one volatile field and then an ordinary field written before that volatile write is most accurate?
Reveal answer
Answer
The volatile read can make prior writes by the publishing thread visible - A volatile read can make earlier writes performed before the corresponding volatile write visible to the reading thread.
Explanation
This is why volatile often works as a publication flag. If a writer fully initializes state and then writes ready = true to a volatile field, a reader that sees ready as true is also guaranteed to observe the prior writes that happened before that volatile write.
Common interview notes
The interview usually turns here toward publication patterns such as ready flags and immutable snapshots.
Question 11
Which tool is the best default when multiple fields must change together under one invariant?
Reveal answer
Answer
synchronized or an explicit lock - synchronized or an explicit lock is the best default when correctness depends on multiple fields changing together.
Explanation
Memory visibility alone is not enough if readers must never observe a half-updated state. Locks provide mutual exclusion plus ordering and visibility, which is what composite invariants usually require.
Common interview notes
A common follow-up is to ask for an example where volatile is correct for a flag but wrong for a state machine.
Question 12
If a reference to a mutable object is stored in a final field, what is true?
Reveal answer
Answer
The reference cannot change, but the object it points to may still mutate - final fixes the reference, not the mutability of the object behind that reference.
Explanation
final helps with initialization safety for the reference itself, but deep immutability still depends on the object graph. If the referenced object exposes mutable state without synchronization, that state can still create race conditions.
Common interview notes
Strong answers distinguish shallow immutability from deep immutability immediately.
Question 13
Which publication approach is generally safe for sharing configuration snapshots across threads?
Reveal answer
Answer
Publish a fully built immutable object through a volatile or final-backed safe path - Publishing a fully built immutable snapshot through a safe publication path is generally a strong approach.
Explanation
Immutable snapshots reduce coordination needs because readers do not modify the shared object. Pairing immutability with safe publication, such as static initialization, volatile publication, or lock-protected assignment, gives predictable visibility.
Common interview notes
This is a great place to mention copy-on-write style designs or replacing whole objects instead of mutating them in place.
Question 14
What is the most accurate reason a busy-spin loop on a non-volatile field is risky?
Reveal answer
Answer
The JVM may hoist or cache the read so the loop never observes updates - The loop is risky because the read may be optimized or cached in a way that prevents timely visibility of another thread's write.
Explanation
Without a memory barrier, the compiler or processor may treat the value as effectively unchanged from the looping thread's perspective. This is the same core visibility issue that makes plain flags unsafe for inter-thread signaling.
Common interview notes
Interviewers may ask for safer alternatives such as volatile, locks, latches, or higher-level concurrency utilities.
Question 15
Which statement about synchronized blocks and the memory model is correct?
Reveal answer
Answer
Unlocking a monitor happens-before a later lock of the same monitor - Unlocking a monitor happens-before a later lock of the same monitor.
Explanation
That ordering rule is why synchronized protects both mutual exclusion and memory visibility. A thread entering the synchronized block after another thread exits the same monitor is guaranteed to observe the writes that were made inside the earlier critical section.
Common interview notes
Good answers connect the rule back to a concrete bug class such as stale reads disappearing once access is consistently synchronized.
Full answer key
Review every answer in one place, with explanations and interview tips below.
1. One thread sets ready = true and another spins until ready becomes true. Without synchronization or volatile, what is the safest assumption?
Answer summary
The reader may never observe the update — The safest assumption is that the reader may never observe the update in a timely way, or at all from the program's point of view.
Without a happens-before relationship, the Java Memory Model does not guarantee visibility of one thread's write to another thread's read. CPU caches, compiler optimizations, and instruction reordering can all contribute to stale observations.
Interview tip: A classic follow-up is how declaring ready as volatile changes the guarantee.
2. What does a happens-before relationship primarily guarantee?
Answer summary
Earlier writes become visible to a later read that is ordered after them — A happens-before relationship guarantees visibility and ordering for memory effects between the related actions.
If action A happens-before action B, then the writes visible at A are guaranteed to be visible to B, subject to the normal rules of the memory model. This is why synchronization, volatile, thread start, thread join, and final-field rules matter.
Interview tip: Good answers mention that happens-before is broader than locking alone and includes several language-level ordering edges.
3. Which statement about volatile is correct?
Answer summary
It provides visibility and ordering guarantees for reads and writes of that variable — volatile provides visibility and certain ordering guarantees for reads and writes of that variable.
A volatile write is visible to later volatile reads of the same variable, and the memory model prevents some reorderings around those accesses. It does not make compound actions such as increment atomic, and it does not replace mutual exclusion for larger critical sections.
Interview tip: Interviewers often ask you to compare volatile with synchronized and atomic classes in one concrete scenario.
4. Why can instruction reordering be legal in correctly synchronized Java programs?
Answer summary
Because the JVM may reorder operations as long as single-thread semantics and memory model guarantees are preserved — Reordering can be legal as long as the observable behavior remains valid under the Java Memory Model.
Compilers and processors may change execution order for performance if the resulting program still respects the guarantees required by synchronization, volatile, final-field semantics, and as-if-serial behavior for a single thread. Unsafely shared state is where those optimizations become visible as bugs.
Interview tip: A strong answer separates source order, execution order, and visibility order instead of treating them as identical.
5. You publish an immutable configuration object through a properly constructed final field reference. Why is that attractive for concurrency?
Answer summary
final fields have special visibility guarantees after safe construction — final fields have special visibility guarantees once the object is constructed safely and then published.
The memory model gives stronger guarantees for final fields than for ordinary mutable fields, which is one reason immutable objects are so useful in concurrent code. However, the object still must not leak this during construction, and referenced mutable state can still be a problem.
Interview tip: Follow-ups often ask whether final on a reference also makes the referenced object immutable. It does not.
6. After threadA calls threadB.start, which statement is true?
Answer summary
Actions in threadA before start happen-before actions in threadB after it begins — Actions in the parent thread before start happen-before actions in the started thread after it begins.
Thread start creates an ordering edge in the Java Memory Model. That is why state prepared before calling start can be safely observed by the new thread without extra publication steps, assuming the object graph itself is not being mutated unsafely later.
Interview tip: The symmetric follow-up is usually about what join guarantees on the way back.
7. What does threadA.join on threadB give threadA after join returns successfully?
Answer summary
It guarantees threadA can see the effects of threadB's completed actions — join establishes that threadA can observe the memory effects of threadB's completed actions after the join returns.
Thread completion and successful join form another happens-before edge. This is why join is not only a coordination tool for waiting, but also a visibility tool for results written before the worker thread finished.
Interview tip: A strong answer connects join to both liveness and visibility instead of treating it as mere blocking.
8. Which pattern is unsafe without volatile or synchronization in a lazily initialized singleton?
Answer summary
Double-checked locking with a non-volatile instance field — Double-checked locking is unsafe when the instance field is not volatile.
Without volatile, another thread can observe a reference to a partially constructed object due to reordering between allocation, assignment, and initialization. Modern Java supports double-checked locking only when the shared instance reference is volatile.
class Holder {
private static volatile Holder instance;
} Interview tip: This is a classic senior-level question. Interviewers usually want you to explain partial construction, not just recite the rule.
9. Why is publishing this from a constructor considered dangerous?
Answer summary
Other threads can observe the object before construction has finished — Publishing this from a constructor is dangerous because another thread may observe the object before initialization is complete.
Escaping this during construction breaks the assumptions behind safe initialization and final-field semantics. Listeners, thread starts, and callbacks registered from constructors are common ways this bug appears in practice.
Interview tip: A good answer names at least one real escape path, such as starting a thread in the constructor or registering a listener.
10. Which statement about reading one volatile field and then an ordinary field written before that volatile write is most accurate?
Answer summary
The volatile read can make prior writes by the publishing thread visible — A volatile read can make earlier writes performed before the corresponding volatile write visible to the reading thread.
This is why volatile often works as a publication flag. If a writer fully initializes state and then writes ready = true to a volatile field, a reader that sees ready as true is also guaranteed to observe the prior writes that happened before that volatile write.
Interview tip: The interview usually turns here toward publication patterns such as ready flags and immutable snapshots.
11. Which tool is the best default when multiple fields must change together under one invariant?
Answer summary
synchronized or an explicit lock — synchronized or an explicit lock is the best default when correctness depends on multiple fields changing together.
Memory visibility alone is not enough if readers must never observe a half-updated state. Locks provide mutual exclusion plus ordering and visibility, which is what composite invariants usually require.
Interview tip: A common follow-up is to ask for an example where volatile is correct for a flag but wrong for a state machine.
12. If a reference to a mutable object is stored in a final field, what is true?
Answer summary
The reference cannot change, but the object it points to may still mutate — final fixes the reference, not the mutability of the object behind that reference.
final helps with initialization safety for the reference itself, but deep immutability still depends on the object graph. If the referenced object exposes mutable state without synchronization, that state can still create race conditions.
Interview tip: Strong answers distinguish shallow immutability from deep immutability immediately.
13. Which publication approach is generally safe for sharing configuration snapshots across threads?
Answer summary
Publish a fully built immutable object through a volatile or final-backed safe path — Publishing a fully built immutable snapshot through a safe publication path is generally a strong approach.
Immutable snapshots reduce coordination needs because readers do not modify the shared object. Pairing immutability with safe publication, such as static initialization, volatile publication, or lock-protected assignment, gives predictable visibility.
Interview tip: This is a great place to mention copy-on-write style designs or replacing whole objects instead of mutating them in place.
14. What is the most accurate reason a busy-spin loop on a non-volatile field is risky?
Answer summary
The JVM may hoist or cache the read so the loop never observes updates — The loop is risky because the read may be optimized or cached in a way that prevents timely visibility of another thread's write.
Without a memory barrier, the compiler or processor may treat the value as effectively unchanged from the looping thread's perspective. This is the same core visibility issue that makes plain flags unsafe for inter-thread signaling.
Interview tip: Interviewers may ask for safer alternatives such as volatile, locks, latches, or higher-level concurrency utilities.
15. Which statement about synchronized blocks and the memory model is correct?
Answer summary
Unlocking a monitor happens-before a later lock of the same monitor — Unlocking a monitor happens-before a later lock of the same monitor.
That ordering rule is why synchronized protects both mutual exclusion and memory visibility. A thread entering the synchronized block after another thread exits the same monitor is guaranteed to observe the writes that were made inside the earlier critical section.
Interview tip: Good answers connect the rule back to a concrete bug class such as stale reads disappearing once access is consistently synchronized.
Try each question on your own, then open "Reveal answer" for the full write-up. For tailored practice and Check feedback on open-ended responses, use PrepAhead in the app - not on blog pages.