library
advancedAtomic Classes & CAS Operations
Use lock-free thread-safe operations on single variables with AtomicInteger, AtomicReference, and compare-and-swap.
An atomic class updates a single variable safely without a lock, using one CPU instruction.
CAS = trying to swap a book on a shelf. You check if 'Java Basics' is still there (expected), grab it, and put 'Java Advanced' in its place (newValue). If someone already swapped it, you notice and try again.
Key Concepts
1
AtomicInteger count = new AtomicInteger();
count.incrementAndGet(); // atomic, lock-free2
Why count++ is not enough. It is three operations — read, add, write — and two threads interleaving
them lose an update. synchronized fixes it by excluding one thread; CAS fixes it by retrying.
count++synchronized
3
Compare-and-set is the primitive underneath.
int old, next;
do {
old = count.get();
next = old * 2;
} while (!count.compareAndSet(old, next));4
compareAndSet(expected, new) writes only if the value is still expected. If another thread changed it,
the call returns false and you loop. No thread ever blocks.
compareAndSet(expected, new)expected
5
The classes.
AtomicInteger, AtomicLong counters, sequence numbers
AtomicBoolean a one-shot flag
AtomicReference<T> swap an object reference
AtomicIntegerArray per-element atomics
LongAdder, LongAccumulator high-contention counters6
updateAndGet saves writing the loop:
count.updateAndGet(n -> n * 2);
ref.updateAndGet(cfg -> cfg.withTimeout(5));updateAndGet
7
Versus synchronized.
no context switch -- a failed CAS retries instead of parking
no deadlock, because nothing is held
but it busy-spins, so heavy contention burns CPUsynchronized
8
LongAdder is the answer to that spin. It keeps a cell per contending thread and sums them on sum(),
so threads rarely collide. Under a dozen threads hammering a counter it is dramatically faster than
AtomicLong — at the cost of an approximate read while writes are in flight.
LongAddersum()AtomicLong
9
The ABA problem is the subtle one. A value goes A to B and back to A; your CAS sees A, succeeds, and
misses that anything happened. It matters when the value is a reference whose identity carries meaning:
10
AtomicStampedReference<Node> pairs the value with a counter11
And the scope limit. CAS protects one variable. Two fields that must change together still need a lock,
or an immutable object swapped atomically through an AtomicReference.
AtomicReference
12
What the interviewer is probing.1. "Why is count++ unsafe even on a volatile int?" Probing: the visibility and atomicity
split. Stalls: "Volatile makes it atomic." Moves up: it is read-modify-write, three operations;
volatile gives visibility, not atomicity. Use AtomicInteger or a lock.
13
2. "How does compareAndSet work?" Probing: the primitive under the class. Stalls: "It locks
briefly." Moves up: a CPU instruction writes only if the value still matches what you read; if
another thread changed it, the call returns false and you retry — nothing blocks.
14
3. "What is the ABA problem?" Probing: the subtle failure of CAS. Stalls: "Never heard of
it." Moves up: a value goes A to B and back to A, so your CAS succeeds having missed that anything
happened; AtomicStampedReference pairs the value with a counter.
15
4. "When is LongAdder better than AtomicLong?" Probing: contention. Stalls: "They are the
same." Moves up: under heavy contention — it keeps a cell per thread and sums on read, so threads
rarely collide, at the cost of an approximate read mid-flight.