🏁
RaceForge
Two tasks, one shared counter — what could go wrong?
▶ Open the concurrency console →What a data race actually is
- Predict. Given two tasks adding to a shared counter, what is the smallest value it could reach?
- Reveal. The engine enumerates every possible interleaving and shows the exact one that loses an update.
- Fix it. Move the counter inside an actor — each add becomes atomic — and watch the whole range of outcomes collapse to one.
The pieces of a race
- Shared state — one variable two tasks can both read and write. The moment it is shared and mutable, a race is possible.
- The non-atomic step —
+= 1is read-modify-write, three operations that can be split apart by another task landing in the middle. - The interleaving — the specific order the two tasks' steps happen to run in. There are many; some are fine, some lose updates.
- The actor — an isolation boundary that lets only one task touch the state at a time, making each operation atomic. The race can no longer be expressed.