Concurrency Risks and Terms

Race conditions exist as soon as the access to common resources (variables or similar) has not been synchronized sufficiently. In other words, there is a race condition when the execution does not always come to a valid state. One could also say that due to the race condition, different results are generated for the same code depending on the thread scheduling.

Deadlocks are situations where threads block each other. This can happen, for example, when locks are acquired in different orders, with one thread needing the lock from the other before it can continue.

Starvation is an impediment to the progress of threads, for example because of fairness issues. A thread can “starve” if it is never woken up or because someone has always acquired the lock faster.

Data races occur with unsynchronized access to the same memory. It always needs at least one write for a Data Race. A race condition is often based on a data race. Because of the synchronized keyword there is no data race on the variable balance. Nevertheless, there can be invalid conditions. So-called lost updates are possible below, because the read and the write are not atomic.

class BankAccount {
   int balance = 0;
   synchronized int getBalance() { return balance; }
   synchronized void setBalance(int x) { balance = x; }

account.setBalance(account.getBalance() + 100);