Atomic variables in Java are part of the java.util.concurrent.atomic
package and provide a way to perform atomic operations on single variables. These operations are thread-safe and ensure that the variable's state is updated consistently without the need for explicit synchronization.
Key Characteristics of Atomic Variables
- Atomicity: Operations on atomic variables are indivisible. This means that once an operation starts, it completes without any interference from other threads.
- Lock-Free: Atomic variables use low-level atomic machine instructions (like compare-and-swap) to ensure thread safety without the overhead of locks.
- Non-Blocking: Since they don’t use locks, atomic variables avoid issues like deadlocks and contention that can occur with traditional locking mechanisms.
How Atomic Variables Work
Atomic variables work by using low-level atomic operations provided by the hardware, such as compare-and-swap (CAS).
Compare-and-swap (CAS) is a low-level atomic operation used in concurrent programming to achieve synchronization without using locks. It is a hardware-supported instruction that operates on a memory location and performs the following steps atomically:
- Read the current value of the memory location.
- Compare the current value with an expected value.
- Update the memory location to a new value if and only if the current value matches the expected value.
The key point is that these steps are performed as a single, indivisible operation, ensuring that no other thread can interfere between the comparison and the update.
Why CAS is Useful
CAS is useful because it allows multiple threads to attempt to update a shared variable concurrently without using locks. If a thread fails to update the variable (because another thread has already changed it), it can retry the operation. This lock-free approach can lead to better performance and scalability in highly concurrent applications.
Example: Using AtomicInteger
with CAS
Let’s look at how AtomicInteger
uses CAS internally to provide atomic operations:java
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
int oldValue, newValue;
do {
oldValue = count.get(); // Read the current value
newValue = oldValue + 1; // Calculate the new value
} while (!count.compareAndSet(oldValue, newValue)); // Attempt to update using CAS
}
public int getCount() {
return count.get(); // Atomically retrieves the current value
}
public static void main(String[] args) throws InterruptedException {
AtomicCounter counter = new AtomicCounter();
// Create multiple threads to increment the counter
Thread t1 = new Thread(counter::increment);
Thread t2 = new Thread(counter::increment);
Thread t3 = new Thread(counter::increment);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
// Get the final count
System.out.println("Final count: " + counter.getCount()); // Should print 3
}
}
Explanation
- Read the Current Value: The
oldValue
is read from theAtomicInteger
using theget()
method. - Calculate the New Value: The
newValue
is calculated by incrementing theoldValue
. - CAS Loop: The
compareAndSet()
method attempts to update theAtomicInteger
fromoldValue
tonewValue
. If the current value of theAtomicInteger
has not changed since it was last read, the update is successful, and the loop exits. If the value has changed (due to another thread's update), the loop retries with the new current value.
Hardware Support for CAS
Modern CPUs provide hardware support for CAS operations, often through specific instructions like CMPXCHG
on x86 architectures. These instructions are designed to perform the read-modify-write sequence atomically, ensuring that no other thread can intervene during the operation.
Advantages of CAS
- Lock-Free: CAS allows for lock-free algorithms, reducing the risk of deadlocks and contention.
- Performance: CAS can be more efficient than traditional locking mechanisms, especially in scenarios with high contention.
- Scalability: CAS-based algorithms can scale better in multi-core systems because they avoid the overhead associated with locks.

If you enjoyed this, please give it some claps to help it reach more people. For more stories like this, follow me.