Fix a counter that loses updates
The code below counts processed orders across a thread pool. In a single-threaded test it is always correct. In production it reports fewer orders than were processed, and the shortfall grows with load.
Fix it. Then answer the harder question: name the exact interleaving that loses an update.
Example
- input
8 threads × 100,000 incrementsoutput800000The buggy version typically reports somewhere between 300,000 and 790,000, and never the same number twice.
Constraints
- The fix must not serialise the whole pool — a synchronized block around the work defeats the point.
- Do not change the number of threads.
Hints
Hint 1
count++ is a read, an add and a write. Nothing stops two threads reading the same value.
Hint 2
volatile makes the write visible. It does not make the three steps one step.
Hint 3
AtomicLong, or LongAdder if the contention is high enough to matter.
Stuck? The lesson behind this problem: 🧵 synchronized and volatile
java
Tab indents · Escape first to tab out
Test cases
These are the specification. Run tests checks your answer against them.
| Case | Input | Expected |
|---|---|---|
| 8 threads, 100k increments each | threads=8, each=100000 | 800000 |
| 1 thread (must not regress) | threads=1, each=100000 | 100000 |
| high contention | threads=64, each=50000 | 3200000 |