Card 04/ 09
All 9 cards
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.
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.
| Written | Reads | Then writes |
|---|---|---|
count++ | The count | The count plus one |
balance -= pence | The balance | The balance less the amount |
if (m.get(k) == null) m.put(k, v) | Whether the key is there | The 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.