Tuesday, July 30

Atomic variables in java


Atomic variables are introduced in java in version 5.0

To understand why atomic variables are introduced lets get through a piece of code 

Public class Calculator {
int i=0;
public int get (){
return i++;
   }
}

This is pretty simple code and work as expected in single threaded environment. 

But does it behave the same way in multithreaded environment as well.

i++ is not a single step operation instead it happens in three steps

1) value to be updated is read
2) manipulation is performed
3) new value is set in variable 

So if mutiple threads call get method simultaneously they will result in operating over i in inconsistent state . one thread might be in progress of incrementing the value and at same time other thread might access the variable and perform increment on same value . So multi step operation results in highly inconsistent data state .

How do we resolve this problem ?

Way to resolve this problem is to allow only one thread at a time to access get methods and perform all three steps completely only then allow other thread to access the method. 

How do we achieve that ? 

Way to achieve that is synchronization. 

public int synchronized get (){
return i++;
}

This will allow only one thread to access method at one time . Thread will take the lock on the object and will release lock while exiting the method . then other thread will take the lock. 

Here multiple threads are working in sequential manner. Although data inconsistency issue is resolved But it has degraded the performance a lot . Now multiple threads are taking as much time as many number of threads execute the get() method.

Way to overcome that is atomic variables . 


 JVM compiles these classes with the better operations provided by the hardware machine, CAS or a Java implementation of the operation using a lock. 

Atomic classes in java are 


  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicReference


All these classes supports compare-and-set (via the compareAndSet() method) . The setters operations are implemented using compareAndSet. These classes supports multi-threaded access and have a better scalability than synchronizing  the operations.

what is compareAndSet?

Quickly read that here 

http://efectivejava.blogspot.in/2013/07/what-is-compare-and-swap-and-compare.html

Here is how we can rewrite our get() method using an AtomicInteger :


public class Calculator{

    private final AtomicInteger var= new AtomicInteger(0);
          public int get(){
            return  var.incrementAndGet();
      }
}

The incrementAndGet()  method is  provided by the AtomicLong and AtomicInteger classes. there are many other methods for other operations like decrementandget() , getandset();

This is faster than the synchronized one and is also thread safe.

No comments:

Post a Comment