Watch how concurrent threads can corrupt shared data when operations aren't atomic. Compare unsafe vs atomic operations side by side.
A race condition occurs when two or more threads access shared data simultaneously, and at least one of them modifies it. The final result depends on the unpredictable timing of thread execution — whoever "wins the race" determines the outcome. This unpredictability leads to bugs that are extremely hard to reproduce and debug.
Example: Imagine two bank tellers trying to update the same account balance at the same time. If the balance is $100 and both read it, then both try to add $50, the balance might end up as $150 instead of $200!
Click "Run Both Demos" to see two scenarios side-by-side: the unsafe version where all threads read the same value before any writes occur (causing lost updates), and the atomic version where each operation is indivisible, ensuring every update is preserved.
counter += 1atomicIncrement()The operation counter += 1 is actually 3 steps:
When threads interleave, they all read the same initial value (0), each computes 1, and each writes 1. Two updates are lost!
Atomic operations are indivisible - the entire read-modify-write happens as one unit.
The counter correctly reaches 3 because each increment builds on the previous result.