Backend Development 7 min read

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.

Java Captain
Java Captain
Java Captain
Understanding Java Counter Implementations: AtomicLong vs LongAdder

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.

distributed systemsJavaconcurrencyAtomicLongCASLongAdder
Java Captain
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.