Inside a computer, the analogue to having multiple real-world bank tellers is called multithreading. A thread,
like a bank teller, can perform a task independent of other threads. And just as two bank tellers can use the
same filing cabinets, threads can share access to objects.
This shared access is simultaneously one of the most useful features of multithreading and one of its greatest
pitfalls. This kind of getmodifyset sequence has what is known as a race hazard or race condition. A race
hazard exists when two threads can potentially modify the same piece of data in an interleaved way that can
corrupt data. In the bank example, imagine that someone walks up to a bank teller to deposit money into an
account. At almost the same time, a second customer asks another teller to handle a deposit into the same
account. Each teller
goes to the filing cabinet to get the current account balance (assuming this is an old-fashioned bank that still
uses paper files) and gets the same information. Then the tellers go back to their stations, add in the deposit,
and return to the filing cabinet to record their separately calculated results. With this procedure, only the last
deposit recorded actually affects the balance. The first modification is lost.
A real bank can handle this problem by having the first teller put a note into the file that says, "I'm working on
this one, wait until I'm finished." Essentially the same thing is done inside the computer: A lock is associated