Atomic variables
Typically, when you need to share an updateable variable among threads, synchronization is used. Synchronization among multiple threads used to be achieved using the synchronized keyword and it was based on an object’s monitor. If a thread is not able to acquire an object’s monitor, that thread is suspended and it has to be resumed later. This way of synchronization (suspending and resuming) uses a great deal of system resources. The problem is not in the locking and unlocking mechanism of the monitor lock; rather it is in suspending and resuming the threads.
An atomic variable uses a lock-free synchronization of a single variable. Note that if your program needs to synchronize on more than one shared variable, you still need to use the old synchronization methods. By lock-free synchronization, I mean that multiple threads can access a shared variable safely using no object monitor lock. JDK takes advantage of a hardware instruction called “compare-and-swap" (CAS) to implement the lock-free synchronization for one variable.
CAS is based on three operands: a memory location M, an expected old value O, and a new value N. If the memory location M contains a value O, CAS updates it atomically to N; otherwise, it does not do anything. CAS always returns the current value at the location M that existed before the CAS operation started. The pseudo code for CAS is as follows:
CAS(M, O, N) { currentValueAtM = get the value at Location M; if (currentValueAtM == O) { set value at M to N; } return currentValueAtM; }
The CAS instruction is lock free. It is directly supported in most modern computers’ hardware. However, CAS is not always guaranteed to succeed in a multi-threaded environment. CAS takes an optimistic approach by assuming that there are no other threads updating the value at location M; if the location M contains value O, update it to N; if the value at location M is not O, do not do anything. Therefore, if multiple threads attempt to update the value at location M to different values simultaneously, only one thread will succeed and others will fail.
Atomic variable classes are named like AtomicXxx, and can be used to execute multiple instructions on a single variable atomically without using any lock. Here, Xxx is replaced with different words to indicate different classes that are used for different purposes; for example, the AtomicInteger class is used to represent an int variable, which is supposed to be manipulated atomically. Twelve classes in the Java class library support read-modify-write operations on a single variable atomically.*1
Instances of classes AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference each provide access and updates to a single variable of the corresponding type. Each class also provides appropriate utility methods for that type. For example, classes AtomicLong and AtomicInteger provide atomic increment methods. One application is to generate sequence numbers, as in:
class Sequencer { private final AtomicLong sequenceNumber = new AtomicLong(0); public long next() { return sequenceNumber.getAndIncrement(); } }
It is straightforward to define new utility functions that, like getAndIncrement, apply a function to a value atomically. For example, given some transformation
long transform(long input)
write your utility method as follows:
long getAndTransform(AtomicLong var) { while (true) { long current = var.get(); long next = transform(current); if (var.compareAndSet(current, next)) return current; // return next; for transformAndGet } }
In addition to classes representing single values, this package contains Updater classes that can be used to obtain compareAndSet operations on any selected volatile field of any selected class. AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater are reflection-based utilities that provide access to the associated field types. These are mainly of use in atomic data structures in which several volatile fields of the same node (for example, the links of a tree node) are independently subject to atomic updates. These classes enable greater flexibility in how and when to use atomic updates, at the expense of more awkward reflection-based setup, less convenient usage, and weaker guarantees.*2
*1 Beginning Java Language Features By Kishori Sharan
*2 Android API java.util.concurrent.atomic








