When writing multi-threaded applications, one of the most common problems experienced are race conditions.
My questions to the community are:
What is a race condition? How do you detect them? How do you handle them? Finally, how do you prevent them from occurring?
Race condition is not only related with software but also related with hardware too. Actually the term was initially coined by the hardware industry.
According to wikipedia:
Software industry took this term without modification, which makes it a little bit difficult to understand.
You need to do some replacement to map it to the software world:
So race condition in software industry means "two threads"/"two processes" racing each other to "influence some shared state", and the final result of the shared state will depend on some subtle timing difference, which could be caused by some specific thread/process launching order, thread/process scheduling, etc.
A "race condition" exists when multithreaded (or otherwise parallel) code that would access a shared resource could do so in such a way as to cause unexpected results.
Take this example:
If you had 5 threads executing this code at once, the value of x WOULD NOT end up being 50,000,000. It would in fact vary with each run.
This is because, in order for each thread to increment the value of x, they have to do the following: (simplified, obviously)
Any thread can be at any step in this process at any time, and they can step on each other when a shared resource is involved. The state of x can be changed by another thread during the time between x is being read and when it is written back.
Let's say a thread retrieves the value of x, but hasn't stored it yet. Another thread can also retrieve the same value of x (because no thread has changed it yet) and then they would both be storing the same value (x+1) back in x!
Example:
Race conditions can be avoided by employing some sort of locking mechanism before the code that accesses the shared resource:
Here, the answer comes out as 50,000,000 every time.
For more on locking, search for: mutex, semaphore, critical section, shared resource.
You can prevent race condition, if you use "Atomic" classes. The reason is just the thread don't separate operation get and set, example is below:
As a result, you will have 7 in link "ai". Although you did two actions, but the both operation confirm the same thread and no one other thread will interfere to this, that means no race conditions!
A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, you don't know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are "racing" to access/change the data.
Problems often occur when one thread does a "check-then-act" (e.g. "check" if the value is X, then "act" to do something that depends on the value being X) and another thread does something to the value in between the "check" and the "act". E.g:
The point being, y could be 10, or it could be anything, depending on whether another thread changed x in between the check and act. You have no real way of knowing.
In order to prevent race conditions from occurring, you would typically put a lock around the shared data to ensure only one thread can access the data at a time. This would mean something like this:
Ok thats 4 questions. one by one answer is as under....
It occurs when the output and/or result of the process is critically dependent on the sequence or timing of other events i.e. e.g. 2 signals are racing to change the output first.
It leads to error which is difficult to localize.
Use Semaphores
And finally,
One way to avoid race condition is using locking mechanism for resources. but locking resources can lead to deadlocks. which has to be dealt with.
A race condition is a kind of bug, that happens only with certain temporal conditions.
Example: Imagine you have two threads, A and B.
In Thread A:
In Thread B:
If thread A is preempted just after having check that object.a is not null, B will do
a = 0
, and when thread A will gain the processor, it will do a "divide by zero".This bug only happen when thread A is preempted just after the if statement, it's very rare, but it can happen.