Open In App

Atomic Variables in Java with Examples

Last Updated : 19 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

An atomic variable in Java is a variable whose operations (like read, write, update) are performed atomically (as an indivisible unit) without needing explicit synchronization. They are part of the java.util.concurrent.atomic package.

Java provides atomic classes such as AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference. These classes contain the following methods.

  1. set(int value): Sets to the given value
  2. get(): Gets the current value
  3. lazySet(int value): Eventually sets to the given value
  4. compareAndSet(int expect, int update): Atomically sets the value to the given updated value if the current value == the expected value
  5. addAndGet(int delta): Atomically adds the given value to the current value
  6. decrementAndGet(): Atomically decrements by one the current value

Syntax:

// Atomic Variable
AtomicInteger var;

Need for Atomic Variable

Consider the below example:

Java
class Counter extends Thread {

    // Counter Variable
    int count = 0;

    // method which would be called upon the start of execution of a thread
    public void run()
    {
        int max = 1_000_00_000;

        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}

public class UnSafeCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();

        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");

        // Threads start executing
        first.start();
        second.start();

        // main thread will wait for both threads to get completed
        first.join();
        second.join();

        // Printing final value of count variable
        System.out.println(c.count);
    }
}

Output
137754082

Explanation:

  • Both threads (first and second) update the same count variable without synchronization.
  • Since count++ is not atomic (it involves read, increment, write), multiple threads may interleave, causing incorrect results.
  • You expect count = 2 * max, but the final value will usually be less because increments get lost.

This issue can be solved using Lock and Synchronization, but not efficiently. 

1. Using lock analogy or synchronization: Synchronization or Locking can solve our problem, but it compromises time efficiency or performance. First, it mandates resource and thread scheduler to control lock. Second, when multiple threads attempt to acquire a lock, only one of them wins, rest are suspended or blocked. Suspending or blocking of threads can have a huge impact on performance.

Java
import java.io.*;
import java.util.concurrent.locks.*;

class Counter extends Thread {

    // Counter Variable
    int count = 0;

    // method which would be called upon the start of execution of a thread
    public synchronized void run()
    {

        int max = 1_000_00_000;

        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}

public class SynchronizedCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();

        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");

        // Threads start executing
        first.start();
        second.start();

        // main thread will wait for both threads to complete execution
        first.join();
        second.join();

        // Printing final value of count variable
        System.out.println(c.count);
    }
}

Output
200000000

2. Using Atomic variable: Here, it will be solved efficiently.

Java
import java.util.concurrent.atomic.AtomicInteger;

class Counter extends Thread {

    // Atomic counter Variable
    AtomicInteger count;

    // Constructor of class
    Counter()
    {
        count = new AtomicInteger();
    }

    // method which would be called upon the start of execution of a thread
    public void run()
    {

        int max = 1_000_00_000;

        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count.addAndGet(1);
        }
    }
}

public class AtomicCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();

        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");

        // Threads start executing
        first.start();
        second.start();

        // main thread will wait for both threads to complete execution
        first.join();
        second.join();

        // Printing final value of count variable
        System.out.println(c.count);
    }
}

Output
200000000

Explanation:

  • AtomicInteger ensures increments happen atomically (no interference between threads).
  • addAndGet(1) replaces count++, making it thread-safe.
  • This removes race conditions and guarantees the correct final count even with multiple threads.

Similar Reads