- Guide to AtomicInteger in Java
- 2.1. AtomicInteger as atomic counter
- 2.2. Compare and swap operations
- What is atomicinteger in java
- Constructor Summary
- Method Summary
- Methods inherited from class java.lang.Number
- Methods inherited from class java.lang.Object
- Constructor Detail
- AtomicInteger
- AtomicInteger
- Method Detail
- get
- set
- lazySet
- getAndSet
- compareAndSet
- weakCompareAndSet
- getAndIncrement
- getAndDecrement
- getAndAdd
- incrementAndGet
- decrementAndGet
- addAndGet
- getAndUpdate
- updateAndGet
- getAndAccumulate
- accumulateAndGet
- toString
- intValue
- AtomicInteger in Java
- AtomicInteger
- Java AtomicInteger Example
Guide to AtomicInteger in Java
The AtomicInteger class protects an underlying int value by providing methods that perform atomic operations on the value. It shall not be used as a replacement for an Integer class.
The AtomicInteger class is part of the java.util.concurrent.atomic package since Java 1.5.
1. Create, get and set value of AtomicInteger
The creation of AtomicInteger is straight forward by calling a constructor. The AtomicInteger provides two methods to get and set the values of it’s instances.
//Initial value is 0 AtomicInteger atomicInteger = new AtomicInteger(); //Initial value is 100 AtomicInteger atomicInteger = new AtomicInteger(100); int currentValue = atomicInteger.get(); //100 atomicInteger.set(1234); //Now value is 1234
2. When to use AtomicInteger in Java
In real life uses, we will need AtomicInteger in two cases:
- As an atomic counter which is being used by multiple threads concurrently.
- In compare-and-swap operations to implement non-blocking algorithms.
2.1. AtomicInteger as atomic counter
To use it as counter, AtomicInteger class provides few methods which perform the addition and subtraction operations atomically.
- addAndGet() – Atomically adds the given value to the current value and returns new value after the addition.
- getAndAdd() – Atomically adds the given value to the current value and returns old value.
- incrementAndGet() – Atomically increments the current value by 1 and returns new value after the increment. It is equivalent to ++i operation.
- getAndIncrement() – Atomically increment the current value and returns old value. It is equivalent to i++ operation.
- decrementAndGet() – Atomically decrements the current value by 1 and returns new value after the decrement. It is equivalent to i- – operation.
- getAndDecrement() – Atomically decrements the current value and returns old value. It is equivalent to – -i operation.
2.2. Compare and swap operations
A compare and swap operation compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value. This is done as a single atomic operation.
The atomicity guarantees that the new value is calculated based on up-to-date information; if the value had been updated by another thread in the meantime, the write would fail.
To support compare and swap operations, this class provides a method which atomically sets the value to the given updated value if the current value == the expected value .
boolean compareAndSet(int expect, int update)
We can see many real time uses of compareAndSet() method in Java concurrent collection classes such as ConcurrentHashMap .
import java.util.concurrent.atomic.AtomicInteger; public class Main < public static void main(String[] args) < AtomicInteger atomicInteger = new AtomicInteger(100); boolean isSuccess = atomicInteger.compareAndSet(100,110); //current value 100 System.out.println(isSuccess); //true isSuccess = atomicInteger.compareAndSet(100,120); //current value 110 System.out.println(isSuccess); //false >>
As discussed above, the primary use of AtomicInteger is when we are in multi-threaded context and we need to perform atomic operations on an int value without using synchronized keyword.
Using the AtomicInteger is equally faster and more readable than performing the same using synchronization.
What is atomicinteger in java
An int value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables. An AtomicInteger is used in applications such as atomically incremented counters, and cannot be used as a replacement for an Integer . However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
Constructor Summary
Method Summary
Atomically updates the current value with the results of applying the given function to the current and given values, returning the updated value.
Atomically updates the current value with the results of applying the given function to the current and given values, returning the previous value.
Atomically updates the current value with the results of applying the given function, returning the previous value.
Atomically updates the current value with the results of applying the given function, returning the updated value.
Methods inherited from class java.lang.Number
Methods inherited from class java.lang.Object
Constructor Detail
AtomicInteger
public AtomicInteger(int initialValue)
AtomicInteger
Method Detail
get
set
public final void set(int newValue)
lazySet
public final void lazySet(int newValue)
getAndSet
public final int getAndSet(int newValue)
compareAndSet
public final boolean compareAndSet(int expect, int update)
weakCompareAndSet
public final boolean weakCompareAndSet(int expect, int update)
Atomically sets the value to the given updated value if the current value == the expected value. May fail spuriously and does not provide ordering guarantees, so is only rarely an appropriate alternative to compareAndSet .
getAndIncrement
public final int getAndIncrement()
getAndDecrement
public final int getAndDecrement()
getAndAdd
public final int getAndAdd(int delta)
incrementAndGet
public final int incrementAndGet()
decrementAndGet
public final int decrementAndGet()
addAndGet
public final int addAndGet(int delta)
getAndUpdate
Atomically updates the current value with the results of applying the given function, returning the previous value. The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads.
updateAndGet
Atomically updates the current value with the results of applying the given function, returning the updated value. The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads.
getAndAccumulate
Atomically updates the current value with the results of applying the given function to the current and given values, returning the previous value. The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads. The function is applied with the current value as its first argument, and the given update as the second argument.
accumulateAndGet
Atomically updates the current value with the results of applying the given function to the current and given values, returning the updated value. The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads. The function is applied with the current value as its first argument, and the given update as the second argument.
toString
intValue
AtomicInteger in Java
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Today we will look into AtomicInteger in Java. Atomic operations are performed in a single unit of task without interference from other operations. Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.
AtomicInteger
Let’s create a simple multi-threaded program where every thread increments the shared count variable 4 times. So if there are two threads, after they finish count value should be 8. JavaAtomic.java
package com.journaldev.concurrency; public class JavaAtomic < public static void main(String[] args) throws InterruptedException < ProcessingThread pt = new ProcessingThread(); Thread t1 = new Thread(pt, "t1"); t1.start(); Thread t2 = new Thread(pt, "t2"); t2.start(); t1.join(); t2.join(); System.out.println("Processing count=" + pt.getCount()); >> class ProcessingThread implements Runnable < private int count; @Override public void run() < for (int i = 1; i < 5; i++) < processSomething(i); count++; >> public int getCount() < return this.count; >private void processSomething(int i) < // processing some job try < Thread.sleep(i * 1000); >catch (InterruptedException e) < e.printStackTrace(); >> >
If you will run above program, you will notice that count value varies between 5,6,7,8. The reason is because count++ is not an atomic operation. So by the time one threads read it’s value and increment it by one, other thread has read the older value leading to wrong result. To solve this issue, we will have to make sure that increment operation on count is atomic, we can do that using Synchronization but Java 5 java.util.concurrent.atomic provides wrapper classes for int and long that can be used to achieve this atomic operation without usage of Synchronization.
Java AtomicInteger Example
Here is the updated program that will always output count value as 8 because AtomicInteger method incrementAndGet() atomically increments the current value by one.
package com.journaldev.concurrency; import java.util.concurrent.atomic.AtomicInteger; public class JavaAtomic < public static void main(String[] args) throws InterruptedException < ProcessingThread pt = new ProcessingThread(); Thread t1 = new Thread(pt, "t1"); t1.start(); Thread t2 = new Thread(pt, "t2"); t2.start(); t1.join(); t2.join(); System.out.println("Processing count=" + pt.getCount()); >> class ProcessingThread implements Runnable < private AtomicInteger count = new AtomicInteger(); @Override public void run() < for (int i = 1; i < 5; i++) < processSomething(i); count.incrementAndGet(); >> public int getCount() < return this.count.get(); >private void processSomething(int i) < // processing some job try < Thread.sleep(i * 1000); >catch (InterruptedException e) < e.printStackTrace(); >> >
Benefits of using Concurrency classes for atomic operation is that we don’t need to worry about synchronization. This improves code readability and chance of errors are reduced. Also atomic operation concurrency classes are assumed to be more efficient that synchronization which involves locking resources.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about us