Wednesday 6 November 2013

About Atomic Operation in Java



What is Atomic Operation in java?


Atomic means each action take place in one step without interruption or we can justify that operation is performed as a single unit of work without the possibility of interference from other operations.

An Atomic operation can't stop in the middle, either it happened completely or doesn't happen at all. No side effects of an atomic operation is visible until the action/operation is complete.

According to java language specification, it  guarantees that

·      Reads and writes are atomic for reference variables and for most primitive variables (for all primitive data types except long and double).
·      Read and write are atomic for all variable declared volatile including long and double variables.

The operation like below is not an atomic operation:-
            int i++;
The upper operation is having 3 steps to complete.
1).    Reading the current value of i;
2).    Incrementing the current value of i;
3).    Writing the modified value of i;

Example of non thread safe code in java:-

package com.gaurav.java.atomictest;

public class Counter {

      private int incrementCounter;

      /*
       * This method is not a thread safe method because ++ is not an atomic
       * operation
       */
      public int getIncrementCounter() {
            return incrementCounter++;
      }

}

In the above example, inside the Counter class the  getIncrementCounter() method is not a thread safe operation because ++(increment operator) is not atomic operation and I mentioned earlier that this can be broken down into three different steps. So if multiple threads call this getIncrementCounter() method simultaneously then each of these three operation may overlap with each other. For example while thread 1 is updating value , thread 2 reads and but still gets old value, which eventually let thread 2 override thread 1 increment and one count is lost because multiple threads are working concurrently.


Writing thread safe code in java for above scenario's
There are many ways to make the above code as thread safe in Java:

            First Approach

With the use of synchronized keyword in Java by providing locking to the getIncrementCounter() method, we can assure that only one thread can execute it at a time which removes possibility of coinciding or overlapping.

package com.gaurav.java.atomictest;

public class SynchronizeCounter {
      private int incrementCounter;

      /* This method is thread safe because of locking provided by synchronization */
      public synchronized int getIncrementCounter() {
            return incrementCounter++;
      }

}

            Second Approach

With the use of Atomic Integer which is available in java.util.concurrent.atomic package with jdk1.5 api, which helps to make this ++ operation atomic and since atomic operations are thread-safe and saves cost of external synchronization.

package com.gaurav.java.atomictest;

import java.util.concurrent.atomic.AtomicInteger;

public class AutomicIntegerCounter {

      AtomicInteger atomicCounterIncrement = new AtomicInteger(0);

      /*
       * This method is thread safe because the counter is incremented
       * automatically using the AtomicInteger class methods
       */
      public int getCountIncrementAutomatically() {
            return atomicCounterIncrement.incrementAndGet();
      }
}

Facts about thread-safety

  • Immutable objects are by default thread-safe because there state can not be changed once created.
  • Read only or Final variables are useful in writing of thread safe programs.
  • With the use of already available thread safe classes like-StringBuffer, HashTable, Vector e.t.c
  • With the use of local variables because each thread has there own copy of local variables.
  • By minimizing sharing of objects between multiple thread we can also avaiod the issue of thread safely.
  • Volatile keyword in Java can also be used to instruct thread not to cache variables and read from main memory and can also instruct JVM not to reorder or optimize code from threading perspective.

No comments:

Post a Comment