Atomic in Java


In this tutorial, we will discuss Atomic in Java, its operations, classes, and variables with detailed examples.

Atomic in Java

Atomic in Java is a very important concept in a multithreading environment. It is one of the concurrent utilities that ensure multiple threads use the shared resources effectively without leading to any issues. This is because these shared resources can change their values during execution in a multithreaded environment. We can implement atomicity in classes, operations, and variables.

Java Atomic classes

The atomic classes are present in the java.util.concurrent.atomic package. It provides lock-free and thread-safe implementation on a shared variable. It also supports atomic operations. The atomic classes have get() and set() methods that are used to read and write the volatile variables.

Below are the different sets of atomic classes present in the concurrent package.

Atomic classDescription
AtomicBooleanUpdates the boolean values atomically
AtomicIntegerUpdates the integer values atomically
AtomicIntegerArrayUpdates the integer array elements atomically
AtomicLongUpdates the long values atomically
AtomicLongArrayUpdates the long array elements atomically
AtomicMarkableReferenceUpdates the object reference with a mark bit atomically
AtomicReferenceUpdates the object reference atomically
AtomicArrayReferenceUpdates the array of object reference atomically

Below are the common methods that are part of the atomic classes

get(): Retrieves the current value

set(): Sets the value of the atomic variable

lazySet(): Eventually sets the value of the atomic variable

compareAndSet(): Sets the value to the updated value if it is equal to the expected value.

Java Atomic operations

Atomic operations or actions that execute together or never execute at all. Below are the three main concepts with respect to atomic operations.

  • Atomic operations may be invisible or undefined and unpredictable.
  • Visible actions occur when the effect of one thread is visible to the other thread.
  • Ordering of actions can occur when the actions in the thread are out of order for the other thread.

We can implement atomic actions by any of the below:

  • Volatile variables
  • Low-level atomic operations(unsafe)
  • Atomic classes

Java Atomic variables

We can use atomic variables to perform atomic operations on a variable. It is important to use these variables in a multithreaded environment else it might lead to concurrency issues.

Atomic in Java

Example: Atomic variable

Below is an example of using an atomic variable in a multithreading environment. This is thread-safe since we are using the counter as an atomic variable and prevents inconsistent results when multiple threads use the same variable. The addAndGet() method increments the value and then retrieves it. Since both operations are performed together, it is atomic in nature and does not affect the results even when there are multiple threads accessing it.

import java.util.concurrent.atomic.*;

class UpdateCounter extends Thread {
  AtomicInteger aiCount;
  
  UpdateCounter(){
    aiCount = new AtomicInteger();
  }
  
  public void run() {
    int max = 10;
    
    for(int i=0;i<max;i++)
      aiCount.addAndGet(1);
    
  }
  
}
public class AtomicDemo {

  public static void main(String[] args) throws InterruptedException {
    UpdateCounter c = new UpdateCounter();
    
    Thread t1 = new Thread(c, "Thread1");
    Thread t2 = new Thread(c, "Thread2");
    
    t1.start();
    t2.start();
    
    t1.join();
    t2.join();
    
    System.out.println(c.aiCount);

  }

}
20

Difference between Atomic, Synchronized and volatile

AtomicSynchronizedVolatile
Applies to variablesApplies to methodsApplies to variables
Ensures visibility along with atomicityEnsures visibility along with atomicityEnsures only visibility and no atomicity
Not ApplicableCan implement any synchronized block or methodNot applicable
Not applicableCan lock the same object or different objectNot applicable

Reference