AtomicInteger class belongs to java.util.concurrent.atmoic package which contain many classes like AtomicInteger,AtomicLong and AtomicBoolean.AtomicInteger is a class that provides you an int value which can be read and write atomically by many threads without interrupting each other
An atomic operation is one which gives guarantee that operation will not get interrupted in between by the thread scheduler .
Atomic classes internally using CAS (compare and swap) algorithm.
How it works in Multi threaded environment ?
Lets see how the below program works in the multi threaded environment with primitive int data type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Count { public static int countIntValue=0; } public class RunnableAtomicIntegerDemo extends Thread{ @Override public void run() { Count.countIntValue++; System.out.print( Count.countIntValue+" "); } public static void main(String[] args) { for(int i=0;i<=15;i++){ new Thread(new RunnableAtomicIntegerDemo()).start(); } } } |
Output :
5 9 10 8 7 7 7 7 7 6 11 12 13 14 16 16
Here you can notice that we have duplicate values because of the multiple thread access. This can be avoided by the following program with the use of Synchronized block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Count { public static int countIntValue=0; } public class RunnableAtomicIntegerDemo extends Thread{ @Override public void run() { synchronized (Count.class) { Count.countIntValue++; System.out.print( Count.countIntValue+" "); } } public static void main(String[] args) { for(int i=0;i<=15;i++){ new Thread(new RunnableAtomicIntegerDemo()).start(); } } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Here we don’t have any duplicate values as we used Synchronized block.
Here comes the benefit of using Atomic classes. Lets see how the above program can be implemented easily by using AtomicInteger class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.util.concurrent.atomic.AtomicInteger; class Count { public static AtomicInteger countValue=new AtomicInteger(0); } public class RunnableAtomicIntegerDemo extends Thread{ @Override public void run() { System.out.print(" "+Count.countValue.incrementAndGet()); } public static void main(String[] args) { for(int i=0;i<=15;i++){ new Thread(new RunnableAtomicIntegerDemo()).start(); } } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Program to demonstrate different methods :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerDemo { public static void main(String[] args) { AtomicInteger atomicInt = new AtomicInteger(5); System.out.println("Value returned by get() is " + atomicInt.get()); atomicInt.set(7); System.out.println("Value returned after calling set(7) is "+ atomicInt.get()); System.out.println("Value returned on calling getAndSet(10) is "+ atomicInt.getAndSet(10)); System.out.println("Value returned after calling getAndSet(10) is "+ atomicInt.get()); atomicInt.addAndGet(5); System.out.println("Value returned after calling addAndGet(5) is "+ atomicInt.get()); atomicInt.incrementAndGet(); System.out.println("Value returned after calling incrementAndGet() is "+ atomicInt.get()); atomicInt.decrementAndGet(); System.out.println("Value returned after calling decrementAndGet() is "+ atomicInt.get()); atomicInt.compareAndSet(15, 20); System.out.println("Value returned after calling compareAndSet(15,20) is "+ atomicInt.get()); } } |
OutPut:
Value returned by get() is 5
Value returned after calling set(7) is 7
Value returned on calling getAndSet(10) is 7
Value returned after calling getAndSet(10) is 10
Value returned after calling addAndGet(5) is 15
Value returned after calling incrementAndGet() is 16
Value returned after calling decrementAndGet() is 15
Value returned after calling compareAndSet(15,20) is 20
Important methods :
1)int get() : This method will return current value of AtomicInteger
2)void set(int value) : This method will set the given value in AtomicInteger
3)int getAndSet(int newValue) : This method will set the given value and then returns the old value defined in AtomicInteger constructor.
4)int addAndGet(int value) : Method will add the given value in the value defined in AtomicInteger Constructor and returns the updated value.
5)int incrementAndGet() : This method will increment the value given in AtomicInteger by 1 and return the updated value.
6)boolean compareAndSet(int expect, int update) : Method will Compare the value given in Atomic class constructor with the expect value given in the method and if both are equal then set to update value and returns true.
7)int decrementAndGet():This method will decrements the value given in AtomicInteger by 1 and return the updated value.
Advantages of Atomic classes:
- It will be very useful when you are working in multithreading environment and required to perform thread safe operations on integer without taking any lock(synchronized method)
- Operations are fast and more readable than primitive synchronized methods.
- It provides many operations like increment and decrement on integer variable which is shared between many threads and hence minimizing the need of complex multithreading.