The java.util.concurrent.atomic classes wrap a single volatile field and expose lock-free, CAS-based read-modify-write operations on it — atomic counters, flags, and reference holders without synchronized.
The main families
- Scalars:
AtomicInteger,AtomicLong,AtomicBoolean— atomic counters and flags withincrementAndGet,getAndAdd,compareAndSet. - References:
AtomicReference<T>— swap an object reference atomically.AtomicStampedReferenceandAtomicMarkableReferenceadd a version stamp / boolean mark to defeat ABA. - Arrays:
AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray— per-element atomic updates without boxing a separate atomic per slot. - Field updaters:
AtomicIntegerFieldUpdaterand friends — apply CAS to an existingvolatilefield of another class via reflection, saving the per-object wrapper allocation. - High-contention accumulators:
LongAdder,LongAccumulator,DoubleAdder— stripe writes across cells to scale under heavy contention.
What the operations give you
Every method is built on compareAndSet. The functional variants take a lambda and run it inside the retry loop, so you express custom atomic updates cleanly:
AtomicReference<BigDecimal> balance = new AtomicReference<>(BigDecimal.ZERO);
// Atomic, lock-free "add to balance" — lambda may run multiple times on contention
BigDecimal updated = balance.updateAndGet(b -> b.add(new BigDecimal("10.00")));
AtomicInteger seq = new AtomicInteger();
int id = seq.getAndIncrement(); // unique id generation, no lock
Memory semantics
The wrapped field is volatile, so a get() is a volatile read and set() a volatile write — full visibility and ordering. There are weaker, faster modes too: lazySet (setRelease, no immediate flush) and the plain/opaque/acquire-release accessors that delegate to VarHandle for fine-grained control when you know the memory model well enough to use them.