Card 04/ 09

ExampleDifficulty: Advanced1 min

The Same Failure Moving Money Between Two Accounts

No counter, no loop and no increment operator. Two threads transferring between accounts, and money that quietly appears.

java
void transfer(Account from, Account to, long pence) {
    if (from.balance >= pence) {
        from.balance -= pence;
        to.balance   += pence;
    }
}

Two threads transfer a hundred pounds out of an account holding a hundred and fifty. Both read the balance on line 2, both find it sufficient, and both proceed. The account ends at minus fifty, and two hundred pounds arrived from a hundred and fifty.

Put this beside the counter and the shared fact comes out: both read a value, computed from it, and wrote it back, and another thread got in between the read and the write. One was three characters and one is four lines; the mechanism is identical.

The same shape in three different places
WrittenReadsThen writes
count++The countThe count plus one
balance -= penceThe balanceThe balance less the amount
if (m.get(k) == null) m.put(k, v)Whether the key is thereThe key, if it was not

The check on line 2 is part of the same operation as the write on line 3, and nothing in the language says so. Recognising that shape is most of what it takes to spot a race before it ships.