Atomics and compare-and-swap question 57 of 180 senior
Why is LongAdder faster than AtomicLong, and when is it not?
- It uses a lock internally
- Correct: It spreads updates across padded cells so threads stop fighting over one cache line, but
sum()must walk every cell and is not atomic - It is a drop-in replacement with no trade-off
- It only works with 64-bit values
Under contention AtomicLong is limited by the cache line holding its value: every CAS invalidates
that line on every other core, so throughput falls as threads are added. LongAdder keeps a base
value plus an array of cells, one per contending thread, each padded onto its own cache line. Threads
update different cells and never invalidate each other.
Measured in the sibling repository at 8 threads: AtomicLong 115 ops/us, LongAdder 1256. Single
threaded they are about equal, 204 against 210, so the striping costs nothing when there is nobody to
contend with.
The trade-off is reading. sum() walks every cell and is not atomic with respect to concurrent
updates, so it is an estimate under load, and it gets slower as the cell array grows. A value read as
often as it is written belongs in an AtomicLong; a metric counter written constantly and read once a
minute belongs in a LongAdder.
Quiz yourself on Atomics and compare-and-swap Suggest a correction