Understanding Java Counter Implementations: AtomicLong vs LongAdder
This article explains the principles, advantages, and drawbacks of Java's AtomicLong and LongAdder counters, describes the CAS operation and its ABA problem, and analyzes why Alibaba recommends LongAdder for high‑concurrency, high‑availability scenarios in distributed systems.
1. Introduction
In distributed systems, counters are a common requirement. To achieve high concurrency and high availability, an appropriate implementation must be chosen. In Java, two typical counter implementations are AtomicLong and LongAdder. Alibaba's technical report recommends using LongAdder instead of AtomicLong.
2. CAS
2.1 What CAS Stands For
CAS stands for Compare‑And‑Swap, an atomic operation corresponding to the CPU instruction cmpxchg .
2.2 Intuitive Understanding of CAS
CAS has three operands: current value A, memory value V, and new value B.
If A equals V, the memory value V is replaced by B.
If A does not equal V, the operation either retries or aborts.
The core of CAS is comparing the current value with the memory value to detect modifications.
2.3 Problems of CAS
CAS suffers from the ABA problem.
When updating, CAS only checks whether the current value equals the memory value, which can lead to incorrect assumptions in concurrent scenarios.
Thread A reads value 10; thread B changes it to 100; thread C changes it back to 10.
When thread A resumes, it sees the value unchanged and proceeds to update, unaware that the value was modified in between.
2.4 Solving the ABA Problem
Java provides AtomicStampedReference , which adds a version stamp to the value, allowing both the memory value and its version to be compared.
Question
Why does Alibaba’s development handbook recommend LongAdder over AtomicLong (better performance by reducing optimistic‑lock retries)?
Answer
AtomicLong performs increments on a single shared variable, causing contention under high concurrency; only one thread succeeds while others repeatedly retry, creating a bottleneck. LongAdder distributes the counter across multiple cells, allowing each thread to update its own cell atomically, dramatically reducing contention.
3. LongAdder
3.1 What is LongAdder
LongAdder, introduced in JDK 1.8 by Doug Lea, is an atomic class in java.util.concurrent.atomic . It provides higher performance than AtomicLong in high‑concurrency scenarios at the cost of extra memory.
It implements a segmented lock strategy, splitting a long value into several 16‑byte cells, each updated by an independent AtomicLong . This allows multiple threads to update different cells simultaneously without interference.
Advantages: high concurrency performance, scalability by adding more cells. Disadvantages: more complex implementation and higher maintenance cost.
3.2 Why LongAdder Is Recommended
LongAdder reduces contention by maintaining a base value and an array of cells, as illustrated in the diagram below.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.