ELI5 · How computers work

Race conditions.

Two people grabbing the last cookie at once because each looked, saw it there, and reached.

Two people share a kitchen with one cookie left. Each glances at the jar, sees a cookie, and reaches in. Because they checked and acted separately, both think the cookie is theirs — and now the count is wrong, or someone is upset.

A race condition is that bug in code. Two threads read and update the same data at almost the same time, and the result depends on the exact, unpredictable order they happen to run in. Most of the time it works; once in a while the steps interleave badly and the data ends up wrong.

  1. Mine!
    the last seat
    1

    Two people both reach for the one last seat at the very same moment.

  2. 100 both read 100
    2

    In code: two threads both read the same value, a balance of 100.

  3. 70 70 70 one withdrawal vanished
    3

    Each subtracts 30 and writes 70 back — so one withdrawal silently disappears.

  4. After you.
    waits its turn
    4

    A lock fixes it: only one thread enters at a time, the other waits its turn.

  5. You go first… no, you.
    each waits for the other
    5

    But locks have their own trap — deadlock, where each thread waits for the other forever.

  6. each its own copy
    6

    The cleanest fix is to not share at all: give each thread its own copy.

Two threads grab the same data at once — and a lock, or sharing nothing, is the fix.

Why they are so nasty

The bug only appears when the timing lines up just wrong, which may be one run in a million. So it passes every test, works in development, and then misbehaves rarely and unpredictably in production. The same code gives different results on different runs, which makes it maddening to reproduce and debug.

How you prevent them

The core fix is to make the critical section — the read-modify-write on shared data — happen as one indivisible step. A mutex (lock) lets only one thread in at a time; atomic operations do small updates as a single uninterruptible instruction. The bigger discipline is to avoid sharing mutable state at all where you can, by giving each thread its own data or passing messages instead.

Locks bring their own hazard: if two threads each hold one lock and wait for the other, neither can proceed — a deadlock.

The real version Mutex & deadlock simulator →
Found this useful?