Happens-before
What happens-before really promises (visibility and ordering, not clock time), every rule from JLS 17.4.5, piggybacking through transitivity, data races and DRF-SC, and the happens-before edges java.util.concurrent documents for queues, executors, futures and latches.
On this page
- Picture it first: a relay baton
- The rules, in plain words
- Under the hood: handing a result to the main thread
- Piggybacking: one volatile carries everything
- What a data race actually is
- The java.util.concurrent promises
- Approach ladder: hand a fully built result to the main thread
- Real world
- Advanced: what happens-before does not say
- How to say it in the interview
🤝 What is happens-before?
Happens-before is Java's promise about what one thread is guaranteed to see of another thread's work. If action A happens-before action B, then everything A wrote is visible to B, and B can't observe it out of order. It is not about clock time: a write can finish 3 seconds before a read on the wall clock and still be invisible to it, because nothing connected the two. You create the connection on purpose, with a lock, a volatile, start(), join() or a java.util.concurrent handoff.
For this lesson, we'll learn the handful of rules that create happens-before, how they chain together so one volatile can carry a whole object graph, what a data race really is, and the big payoff: if your program has no data races, you get to reason about it as if threads took simple turns. Interviewers love this topic because it's the actual contract under synchronized, volatile and every concurrent collection. Candidates who can say "unlock happens-before the next lock of the same monitor" sound like they understand Java. Candidates who say "volatile flushes the cache" sound like they read a blog post in 2009.
What you’ll learn
- Explain happens-before as a promise of visibility and ordering between actions, and why it is not wall-clock time
- List the rules: program order,
unlock→ laterlockof the same monitor,volatilewrite → later read,Thread.start(),join()/isAlive(),interrupt(), default values and transitivity - Use piggybacking to publish plain fields safely through a single
volatilewrite or lock release, and say why the payload must be written first - Define a data race in JMM terms and state the DRF-SC guarantee (correctly synchronized programs appear sequentially consistent)
- Tell a data race from a race condition, and explain why
Thread.sleep()creates no happens-before edge - Quote the
java.util.concurrentMemory Consistency Properties:put→take,submit→ task, task →Future.get(),countDown()→await(), mapput→get - Pick between a naive flag,
join()/volatileand a Future, BlockingQueue or CompletableFuture handoff, with the trade-offs - Describe how HotSpot implements the edges with fences (x86 TSO vs AArch64
ldar/stlr) without confusing the contract with CPU caches
Premium lesson
Keep reading with the Java Pass
The rest of this lesson is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.
- Picture it first: a relay baton
- The rules, in plain words
- Under the hood: handing a result to the main thread
- Piggybacking: one volatile carries everything
- What a data race actually is
- The java.util.concurrent promises
- Approach ladder: hand a fully built result to the main thread
- Real world
- Advanced: what happens-before does not say
- How to say it in the interview
From ₹299 · one-time payment · No auto-renewal
Further reading (12)
- Java Language Specification (Java SE 21) §17.4: Memory Model: §17.4.4 synchronization order and synchronizes-with, §17.4.5 happens-before order, data races and correctly synchronized programs, §17.3 sleep and yield have no synchronization semantics, §17.7 long/double tearing
- java.util.concurrent package summary (Java SE 21): Memory Consistency Properties: the documented happens-before edges for concurrent collections, executors, futures, synchronizers, Exchanger, CyclicBarrier and Phaser
- JSR 133 (Java Memory Model) FAQ, Manson and Goetz: what synchronization does, what volatile does, why the old model was broken
- Aleksey Shipilev: Java Memory Model Pragmatics: happens-before, synchronization order, DRF-SC, and what HotSpot emits for volatile on x86 and ARM
- Aleksey Shipilev: Close Encounters of The Java Memory Model Kind: myths about caches and flushing, piggybacking pitfalls, benign races
- Doug Lea: Using JDK 9 Memory Order Modes: plain, opaque, release/acquire and volatile modes; how release/acquire maps to happens-before
- OpenJDK jdk21u: FutureTask.java: outcome is non-volatile, protected by reads and writes of the volatile state field: piggybacking in the JDK
- Paul Tyma: A Beautiful Race Condition (Mailinator blog, 2009): unsynchronized HashMap resize corrupting buckets and spinning at 100% CPU
- OpenJDK jcstress: stress harness and samples that expose JMM-allowed outcomes on real hardware
- Java Concurrency in Practice (Goetz et al., 2006): §3.1 visibility, §16.1 the JMM and happens-before, §16.1.4 piggybacking on synchronization
- JEP 421: Deprecate Finalization for Removal: finalizers deprecated for removal in Java 18; the constructor-to-finalizer edge is legacy
- Java Code Geeks: The Java Memory Model Explained, Happens-Before and Concurrency Semantics: background reading