Card 05/ 09

ConceptDifficulty: Advanced1 min

The Other Failure: What One Thread Can See of What Another Wrote

A worker loop that checks a boolean flag on every pass. Another thread sets the flag to true. The loop keeps going, for minutes, on a value that was changed long ago.

java
class Worker implements Runnable {
    boolean stopped = false;

    public void run() {
        while (!stopped) { doWork(); }
    }

    void stop() { stopped = true; }
}

Nothing interleaved and nothing was lost. This is a different failure: a write that happened and is not visible to the thread that needs it.

Each processor core has its own caches, and the compiler and the processor are both allowed to reorder and to keep values in registers, as long as a single thread's own view stays consistent. Nothing in that guarantee says anything about what a second thread sees, or when.

The two failures, and what each one is
Compared onA raceA visibility problem
What went wrongTwo threads interleaved mid-operationA write is not seen by another thread
SymptomA wrong valueA stale value, sometimes forever
Fixed byMaking the operation atomicPublishing the write
Shows upUnder loadOften only when optimised, after warm-up

So "it works on my machine" is even less reassuring here than usual. A visibility bug often appears only once the virtual machine has decided the loop is hot enough to optimise, which is well after the first thousand passes.