When two or more threads access or try to change the shared data at the same time, a race condition, which is another type of concurrency bug, occurs. This means a situation where the output of a piece of logic requires that interleaved code is run in a particular order—an order that cannot be guaranteed.
A classic example is of a bank account, where one thread is crediting the account and another is debiting the account. An account operation requires us to retrieve the value, update it, and send it back, which means the ordering of these instructions can interleave with each other.
For example, assume an account starts with $100. Then, we want to credit $50 and debit $100. One possible ordering of the instructions can be something like this:
<credit thread> | <account balance> | <debit thread> |
start value = 100 | ||
get current balance... |