How do the Java atomic classes avoid locks, and what operations do they support?
The classes in java.util.concurrent.atomic provide atomic read-modify-write operations on a single variable without taking a lock. The mechanism is a compare-and-set instruction provided by the processor — a single CPU operation that atomically compares the current value with an expected value and swaps in a new one if they match. Because the hardware performs the whole thing as one indivisible step, no other thread can interleave with it.
That makes them lock-free rather than merely fast: no thread ever blocks waiting for a monitor, so there is no contention and no priority inversion. It also means there is no deadlock risk from them.
The operations are consistent across the family. get and set read and write. incrementAndGet, decrementAndGet, addAndGet and getAndIncrement do the arithmetic atomically, with the difference being whether the new or the old value is returned. compareAndSet swaps only if the value is still what you expect, and returns a boolean. updateAndGet applies a function to the current value atomically, and accumulateAndGet does the same with a binary function.
There are specialised classes for the primitive types — AtomicInteger, AtomicLong, AtomicBoolean, and the floating-point pair — plus AtomicReference for objects and AtomicReferenceArray for arrays. And the array classes have a notable design: unlike the plain atomic classes, they support weakly consistent iteration, where the iterator reflects the state at or since the iteration began rather than throwing when the array is modified.