Threads A and B each increment the shared variable count. The expected result is two, but an interleaving can produce one. Use the buttons to choose their execution order.
A simulator illustrating a lost update by splitting count++ into three steps
Quick examples
Choose the order: press either thread's button
Yellow marks each thread's next instruction. Interleave A and B demonstrates a lost update.
count++ is not necessarily atomic
Although it occupies one source-code line, this model breaks count++ into reading memory, incrementing a register, and writing back. A context switch between these steps can expose an interleaving.
If B runs just after A reads zero, B also reads zero. Each computes one, and the second write overwrites the first. One increment is lost. A result that depends on an uncontrolled execution interleaving is a race condition.
Critical section
The code that accesses shared data is a critical section. Protecting the whole sequence so only one thread enters at a time makes the result consistently two. Tools for coordinating access include Mutexes and Semaphores.