Saturday, September 21, 2013

Race condition in Concurrency

The situation where multiple threads try to operate on a shared resource without proper synchronization  and sequence of their operations interleave is  Race Condition ( Also see Thread interference and Memory consistency errors) .

Example 1 .
The most basic example to describe a Race condition is a Counter class  that increments value of an instance variable . 
class Counter {  
    private int c = 0;  
  
    public void increment() {  
        c++;  
    }  
}
Note :
It seems that the increment operation is atomic ( Atomic operations can't be interleaved by threads ) but it is not . It can further be divided into three steps : 
1. Read the value c. 
2. Increment the value . 
3. Write the incremented value.


Lets imagine that two threads A and B increments the value of instance variable c . Ideally if there is no interleaving of thread's operations , the value of the variable should be 2 as both the threads increment it by 1 . Lets see one of the possible scenario where thread's operations interleave 

Thread A : Read  c ( which is 0 ).
Thread B : Read  c ( Still 0 ).
Thread A : Increments the value by 1.
Thread A : Write the value ( Now c is 1 )
Threab B : Increments the value  
Thread B : Write the value ( Still c is 1 ) 

Here we can see that due to interleaving of Read operations of two threads , the final value of the variable c is 1 and not 2. 

Example 2 .
Below is a short snippet from a singleton class . Here first the code checks whether the instance is null and then creates a new object . The purpose of this code is to ensure that there is only one instance of MySingleton class. 
public MySingleton getInstance(){
   if (instance == null){
       instance  = new MySingleton();
   }
}
Now lets consider that there are two threads trying to get an instance of MySingleton class by calling the method getInstance() . It might be possible , due to interleaving of thread's operations , that both the thread sees the value of instance as null  and in that case , two objects will get created by the threads . 

How to fix the problem ?
Race conditions can be avoided by proper synchronization of the code . As an application developer , you have to enforce locking to make sure that only one thread enters a critical section at a time  and the result of the  thread is visible to others once it  comes out of the synchronized block .


2 comments :

  1. Thanks a lot for your great post.your article is very interest.i hope you will give more interest post.

    ReplyDelete
  2. A singleton class where we just check the object for null before creating a new one is also an example of race condition. In a multi threaded env. that may result in 2 instances of a Singleton class.

    ReplyDelete