In computer science, compare-and-swap (CAS) is an atomic instruction used in multi-threading to achieve synchronization. It compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value. This is done as a single atomic operation. The atomicity guarantees that the new value is calculated based on up-to-date information; if the value has been updated by another thread in the meantime, the write would fail.
What is AtomicInteger class and how it works internally
Upasana | August 03, 2019 | 2 min read | 963 views | Multithreading and Concurrency
Java 5 introduced java.util.concurrent.atomic
package with a motive to provide:
A small toolkit of classes that support lock-free thread-safe programming on single variables.
AtomicInteger uses combination of volatile & CAS (compare and swap) to achieve thread-safety for Integer Counter. It is non-blocking in nature and thus highly usable in writing high throughput concurrent data structures that can be used under low to moderate thread contention.
Since the compare-and-swap occurs (or appears to occur) instantaneously, if another process updates the location while we are in-progress, the compare-and-swap is guaranteed to fail.
Thread Contention
Essentially thread contention is a condition where one thread is waiting for a lock/object that is currently being held by another thread. Waiting thread, thus cannot use that object until the other thread has unlocked that particular object.
How is volatile different from AtomicInteger
Read & write to volatile variables have same memory semantics as that of acquiring and releasing a monitor using synchronized code block. So the visibility of volatile field is guaranteed by the JMM (Java Memory Model).
AtomicInteger class stores its value field in a volatile variable, thus it is a decorator over the traditional volatile variable, but it provides unique non-blocking mechanism for updating the value after requiring the hardware level support for CAS (compare and set/swap). Under low to moderate thread contention, atomic updates provides higher throughput compared to synchronized blocking increment operation.
Here is the implementation for getAndIncrement() method of AtomicInteger Class (as of Java 7).
class AtomicInteger {
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
//Rest of the implementation
}
You can see that no lock is acquired to increment the value, rather CAS is used inside infinite loop to update the new value, that’s why it can be used to write scalable application where thread contention is low to medium.
AtomicInteger class is best candidate for implementing thread-safe counters in your application.
CAS Applications
-
Developing Thread safe Atomic Adders for integer, long and double.
-
Developing Atomic Accumulators that perform good under high thread contention.
-
CAS is highly useful in developing non-blocking concurrent algorithms.
Main classes in java.util.concurrent.atomic package
-
AtomicBoolean
-
AtomicInteger
-
AtomicIntegerArray
-
AtomicLong
-
AtomicReference - An object reference that may be updated atomically
-
DoubleAccumulator
-
DoubleAdder
-
LongAdder
-
LongAccumulator - provides better performance compared to its Atomic counterpart in high thread contention scenarios (many threads updates, only few read)
Multithreading and Concurrency:
- Java 8 Parallel Stream custom ThreadPool
- Java Concurrency Interview Questions
- ConcurrentModificationException in Java
- What is purpose of Collections.unmodifiableCollection
- Removing elements while iterating over a Java Collection
- ThreadLocal with examples in Java
- Design an Immutable class that has an java.util.Date member
Top articles in this category:
- What is Immutable Class in Java
- Discuss internals of a ConcurrentHashmap (CHM) in Java
- What are four principles of OOP, How aggregation is different than Composition?
- What is difference between Vector and ArrayList, which one shall be preferred
- What is purpose of Collections.unmodifiableCollection
- What is volatile keyword in Java
- What is difference between HashMap and HashSet