Thursday, 9 June 2016

AtomicInteger in Java Concurrency

AtomicInteger class provides an int value that may be updated atomically. This class resides in the java.util.concurrent.atomic package which has classes that support lock-free, thread-safe programming on single variables. Apart from AtomicInteger some of the other classes are AtomicLong, AtomicReference, DoubleAccumulator.

These atomic variable classes in Java concurrency like AtomicInteger, AtomicLong uses non-blocking algorithm. These non-blocking algorithms use low-level atomic machine instructions such as compare-and-swap instead of locks to ensure data integrity under concurrent access.

Classes in this package java.util.concurrent.atomic provides methods that can get, set or compare value as an atomic operation i.e. without any interruption. There is no need to explicitly use any locking or synchronization.

AtomicInteger Constructor

AtomicInteger class has two constructors -

  • AtomicInteger() - Creates a new AtomicInteger with initial value 0.
  • AtomicInteger(int initialValue) - Creates a new AtomicInteger with the given initial value.

Atomic operations

AtomicInteger class provides atomic methods for getting, setting, incrementing and decrementing variables like getAndIncrement(), getAndDecrement(), decrementAndGet(), getAndSet() etc.

From the method names itself you can easily deduce that these are atomic methods as example if you take getAndIncrement() method which is doing three operatios.

  • Gets the value
  • Increment the value by 1
  • Sets the updated value back

But these 3 operations are done as a single unit i.e. atomic operation. Either all 3 succeed or none.

There is also a compareAndSet(int expect, int update) method which atomically sets the value to the given updated value if the current value is equal to the expected value.

Example code

In banking applications where you need to process several documents there is a very common requirement to provide sequence numbers for the processed documents.

In a multi-threaded environment it can easily be achieved by using AtomicInteger and the atomic operation getAndIncrement().

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntDemo {

 public static void main(String[] args) {
  AtomicInteger ai = new AtomicInteger(0);
  new Thread(new IncThread(ai)).start();
  new Thread(new IncThread(ai)).start();
  new Thread(new IncThread(ai)).start();
 }

}

class IncThread implements Runnable{
 AtomicInteger ai = null;
 IncThread(AtomicInteger ai){
  this.ai = ai;
 }
 
 @Override
 public void run() {
  System.out.println("Value - " + ai.getAndIncrement() + " for " + Thread.currentThread().getName()); 
 }
 
}

Output

Value - 0 for Thread-0
Value - 2 for Thread-2
Value - 1 for Thread-1

Note that output may differ in different runs.

That's all for this topic AtomicInteger in Java Concurrency. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. AtomicLong in Java Concurrency
  2. Non-blocking algorithms
  3. Busy spinning in multi-threading
  4. Blocking methods in Java Concurrency
  5. Java Concurrency interview questions

You may also like -

No comments:

Post a Comment