Waiting with if instead of while
A hard Java puzzle in the threading and race conditions family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 7. Play this one as a puzzle without the answer.
What is wrong
A thread can wake up spuriously, or another consumer can take the message first after notifyAll. With if, the waiting thread does not recheck the condition and calls remove on an empty queue, which throws NoSuchElementException.
The fix
How to avoid it next time
Always wait in a loop that rechecks the condition. Prefer BlockingQueue, which handles all of this.
Want the background? Read Producer-consumer with blocking queues in the Java concepts library.
About threading and race conditions
Without synchronization, threads can see stale values and interleave read-modify-write sequences. A volatile field gives visibility but not atomicity, and check-then-act sequences are never atomic by themselves.
In code review: For every shared variable ask who writes it, who reads it, and what protects it. Prefer atomic classes, concurrent collections and immutable objects.
More puzzles in this family
Frequently asked questions
What is the bug in "Waiting with if instead of while"?
A thread can wake up spuriously, or another consumer can take the message first after notifyAll. With if, the waiting thread does not recheck the condition and calls remove on an empty queue, which throws NoSuchElementException. The faulty line is line 7: if (queue.isEmpty()) {
How do I fix it?
Replace it with: while (queue.isEmpty()) { wait(); }. Always wait in a loop that rechecks the condition. Prefer BlockingQueue, which handles all of this.
How do I catch threading and race conditions in code review?
For every shared variable ask who writes it, who reads it, and what protects it. Prefer atomic classes, concurrent collections and immutable objects.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.