Condition Variables — wait, notify & the while-loop trap
Waiting efficiently for a condition
A worker often must wait until some state is true — a queue is non-empty, a connection is ready. Spinning
in a loop burns a CPU. A condition variable lets a thread release the lock and sleep until
another thread signals that the state changed, then wake and re-check. In Java this is
Object.wait()/notify() (or Condition.await()/signal()).
The mechanism
Inside a synchronized block, wait() atomically releases the lock and parks the thread in
the monitor's wait-set. Another thread takes the lock, changes state, and calls
notify(), moving a waiter back to compete for the lock. When the waiter re-acquires it,
wait() returns — and it must re-check the condition.
The #1 bug: if instead of while
// BROKEN
synchronized (q) {
if (q.isEmpty()) q.wait(); // wakes up -> assumes non-empty -> may be wrong
return q.remove(); // throws if another consumer already drained it
}
// CORRECT
synchronized (q) {
while (q.isEmpty()) q.wait(); // re-check after every wakeup
return q.remove();
}
Why while is mandatory: spurious wakeups (the JVM may wake a waiter for no reason)
and stale wakeups (another consumer grabbed the item between notify and your re-acquire). Re-check,
always.
notify vs notifyAll
notify() wakes one arbitrary waiter; notifyAll() wakes all. Use
notifyAll() unless every waiter is waiting on the identical condition — otherwise you risk a
lost wakeup (you wake a thread whose condition still isn't satisfied while the right one sleeps on).
In Go: channels instead
Go rarely uses condition variables (sync.Cond exists but is uncommon). The idiom is to
wait on a channel — a receive blocks until a sender signals, and select waits on
several conditions at once. The bounded buffer is just a buffered channel; "wait until non-empty" is "receive from
the channel":
items := make(chan Item, 100) // buffered = bounded buffer
go func(){ items <- produce() }() // producer
it := <-items // consumer blocks until an item exists — no wait/notify, no while-loop bug
That's the CSP payoff: the channel is the condition variable, with the re-check designed away.
Takeaways
wait()releases the lock and sleeps;notify()wakes a waiter to re-compete.- Always re-check in a
while— spurious and stale wakeups are real. - Prefer
notifyAll()unless all waiters share one condition (avoid lost wakeups). - Go replaces all of this with channels +
select.
Re-authored for this guide; monitor/wait-set diagram hand-authored as SVG. Follows Java Concurrency in Practice ch. 14 and The Little Book of Semaphores. See also: Semaphores, Producer-Consumer, Go Concurrency.
🤖 Don't fully get this? Learn it with Claude
Stuck on Condition Variables — wait, notify & the while-loop trap? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Condition Variables — wait, notify & the while-loop trap** (Concurrency) and want to truly understand it. Explain Condition Variables — wait, notify & the while-loop trap from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Condition Variables — wait, notify & the while-loop trap** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Condition Variables — wait, notify & the while-loop trap** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Condition Variables — wait, notify & the while-loop trap** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.