Atomic Variables in Java with Examples
Last Updated :
17 Nov, 2025
Atomic is a type of variable that performs read, write and update in a single uninterruptible step, ensuring thread-safe operations and preventing race conditions
- It ensures data consistency without using synchronization or locks.
- It improves performance through non-blocking, lock-free operations.
- Simplify thread-safe programming for common operations like increment and compare-and-set.
Example: AtomicInteger in Multi-threading
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);
}
}
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.
Example: Without Atomic Variables (Unsafe Code)
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);
}
}
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.
Types of Atomic Variables in Java
Below are some commonly used atomic variable types in Java.
Types of Atomic Variables1. AtomicInteger
AtomicInteger provides atomic operations (increment, decrement, add, etc.) on integer values without synchronization.
Java
import java.util.concurrent.atomic.AtomicInteger;
public class GFG{
public static void main(String[] args){
AtomicInteger count = new AtomicInteger(5);
count.incrementAndGet(); // 6
count.addAndGet(3); // 9
System.out.println("Final Value: " + count.get());
}
}
2. AtomicLong
AtomicLong supports atomic operations on long values for thread-safe numeric computations.
Java
import java.util.concurrent.atomic.AtomicLong;
public class GFG{
public static void main(String[] args) {
AtomicLong counter = new AtomicLong(100);
// adds 50, returns old value
counter.getAndAdd(50);
System.out.println("Updated Value: " + counter.get());
}
}
3. AtomicBoolean
AtomicBoolean represents a boolean value that can be atomically updated for safe flag-based operations.
Java
import java.util.concurrent.atomic.AtomicBoolean;
public class GFG {
private static AtomicBoolean flag
= new AtomicBoolean(false);
public static void main(String[] args)
{
if (flag.compareAndSet(false, true)) {
System.out.println(
"Operation performed only once!");
}
else {
System.out.println("Already performed!");
}
}
}
OutputOperation performed only once!
4. AtomicReference
AtomicReference allows atomic read and write of object references, useful for non-primitive data.
Java
import java.util.concurrent.atomic.AtomicReference;
public class GFG{
public static void main(String[] args){
AtomicReference<String> message
= new AtomicReference<>("Hello");
message.compareAndSet("Hello",
"Hi, from AtomicReference!");
System.out.println("Current Message: "
+ message.get());
}
}
OutputCurrent Message: Hi, from AtomicReference!
5. AtomicIntegerArray
AtomicIntegerArray enables atomic operations on elements of an integer array for thread-safe updates.
Java
import java.util.concurrent.atomic.AtomicIntegerArray;
public class GFG {
public static void main(String[] args)
{
AtomicIntegerArray numbers
= new AtomicIntegerArray(new int[] { 1, 2, 3 });
numbers.incrementAndGet(
1); // Increment element at index 1
System.out.println("Array after update: "
+ numbers);
System.out.println("Value at index 1: "
+ numbers.get(1));
}
}
OutputArray after update: [1, 3, 3]
Value at index 1: 3
Commonly used methods in Atomic classes
Explore
Java Basics
OOP & Interfaces
Collections
Exception Handling
Java Advanced
Practice Java