Race Condition: When multiple threads "race" for access to a resource. Only occur when one or more threads write to resource. We can avoid race conditions by making sure that no two processes enter their Critical Sections at the same time.
Critical Section: A Critical Section is a code segment that accesses shared variables and has to be executed as an atomic action. It means that in a group of cooperating processes, at a given point of time, only one process must be executing its critical section.
volatile: The Java volatile
keyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache.
starvation: when shared resources are made unavailable for long periods by "greedy" threads.
causes of starvation:
- Threads with high priority swallow all CPU time from threads with lower priority.
Threads are blocked indefinately waiting to enter a synchronized block, because other threads are constantly allowed access before it. (Java's synchronized code block doesn't guarantee the entering sequence.)
Threads waiting on an object (called wait() on it) remain waiting indefinitely because other threads are constantly awakened instead of it. (notify() method doesn't guarantee what thread is notified.)
fairness: solution to starvation
- use
ReetrantLock
with Fair policy.
Slipped Conditions: After the conditions are checked, before the thread execute next statements, the condition is changed by another thread.
To avoid slipped conditions the testing and setting of the conditions must be done atomically by the thread doing it, meaning that no other thread can check the condition in between the testing and setting of the condition by the first thread.