Java AtomicInteger
last modified May 25, 2025
In this article, we work with Java's AtomicInteger
.
AtomicInteger
provides an integer variable that can be read and
written atomically. It ensures that operations on the variable are thread-safe,
preventing issues like lost updates in concurrent environments.
AtomicInteger is a class within the java.util.concurrent.atomic
package that provides an atomic and thread-safe way to represent and manipulate
an integer primitive data type.
AtomicInteger
is a synchronization primitive. It provides atomic
operations for integer values, ensuring thread-safe access and modification.
Unlike traditional locks, which can introduce performance overhead,
AtomicInteger
leverages low-level atomic instructions to maintain
data consistency without blocking threads. Its primary purpose is to handle
concurrent updates efficiently while avoiding race conditions.
Key characteristics:
-
Atomic operations:
AtomicInteger
guarantees that read and write operations on the underlying integer value are atomic. This means each operation executes as a single, indivisible unit, even if multiple threads are trying to access the value concurrently. This prevents inconsistencies and data races that can occur with regular integer variables in a multithreaded environment. -
Thread-safety: By ensuring atomic operations,
AtomicInteger
makes it safe to use the same integer value across multiple threads without requiring explicit synchronization mechanisms like locks. This simplifies thread-safe programming and reduces the risk of concurrency issues. - Common operations: The class provides various methods for atomically performing operations on the integer value, such as retrieving the current value, setting a new value, incrementing or decrementing the value, and performing compare-and-swap operations.
Benefits of using AtomicInteger
:
- Prevents data races: Guaranteeing atomic operations avoids inconsistencies that can arise when multiple threads try to read or write the same integer value simultaneously.
- Simplifies concurrent programming: Eliminates the need for complex synchronization code in scenarios where multiple threads access an integer variable.
- Improved performance: Atomic operations can be more efficient than using locks, particularly for frequently accessed variables.
Use cases for AtomicInteger
:
-
Counters:
AtomicInteger
is ideal for representing counters that are incremented or decremented by multiple threads in a concurrent environment, such as tracking website visitors or active network connections. - Sequence numbers: It can be used to generate unique and atomically incremented sequence numbers, useful for purposes like logging or transaction IDs.
-
State flags:
AtomicInteger
can serve as a simple flag variable that multiple threads can set or reset atomically, indicating a specific state or condition.
Counter example
In the next example, we generate 500 threads. Each thread increments a counter.
class Counter { private final AtomicInteger counter = new AtomicInteger(0); public void inc() { counter.getAndIncrement(); } public int get() { return counter.get(); } } void main() throws InterruptedException { final Counter counter = new Counter(); // 500 threads for (int i = 0; i < 500; i++){ var thread = new Thread(counter::inc); thread.start(); } // sleep three seconds Thread.sleep(3000); System.out.println("Value: " + counter.get()); }
In the end, the counter should be 500.
private final AtomicInteger counter = new AtomicInteger(0);
The counter is an AtomicInteger
initiated to 0.
public void inc() { counter.getAndIncrement(); }
The inc
method increments the counter safely.
public int get() { return counter.get(); }
The get
method returns the current value of the counter.
Source
Java AtomicInteger - language reference
In this article we have worked with AtomicInteger
in Java.
Author
List all Java tutorials.