Card 02/ 09

ConceptDifficulty: Intermediate1 min

Atomic Operations: Why count++ Is Three Steps

Read, add and write, and another thread can get in between any two of them.

An operation is atomic when no other thread can see it half done or run in the middle of it. count++ looks like one thing happening, and it is not atomic: it is three separate steps, and the gaps between them are where an update goes missing.

What count++ actually does, in order
StepWhat happens
ReadFetch the current value of count
AddWork out that value plus one
WriteStore the result back into count

Another thread can run between any two of those steps. If both threads read 41 before either writes, both work out 42, and both write 42: two increments, and the count went up by one.

Two threads reading the same value before either writes loses one increment

count++ is not the only one. balance = balance - amount is not atomic, nor is if (map.get(k) == null) map.put(k, v), nor anything else that reads a value, computes from it, and writes it back.

So the question to ask of any line that touches shared state is how many steps it really is. Reading a field is one step and writing one is one step; everything between them is a gap another thread can get into. A plain long or double is the rare exception even there: Java allows a single write to one to be split into two 32-bit halves, unless the field is volatile, a modifier that makes reads and writes of it whole and visible to every thread.