longadder 性能优于 atomiclong 的本质是减少争抢而非更原子,通过 base + cells 分散写操作、防伪共享及扩容机制降低 cas 失败率;但以更高内存占用和最终一致性为代价,适用于写多读少场景。

LongAdder 比 AtomicLong 性能更高,核心不是“更原子”,而是“更少争抢”——它把所有线程抢同一个内存地址的热点,拆成多个线程各自更新不同槽位的分散操作。
单点竞争 vs 多槽分散
AtomicLong 所有写操作都压在 value 这一个 volatile 字段上,底层靠 CAS 循环重试。100 个线程同时调 incrementAndGet(),大概率 99 个失败自旋,CPU 白转、缓存行反复失效。
LongAdder 则采用 base + cells 数组 结构:
- 低并发时:所有线程走
base,和 AtomicLong 行为一致,零额外开销 - 首次发生竞争:初始化长度为 2 的
cells数组,线程按哈希(getProbe())落到某个 Cell - 高并发持续竞争:自动扩容 cells(2→4→8…最多到 CPU 核心数),让线程尽量写自己的 Cell,互不干扰
硬件友好设计:防伪共享
JDK 8+ 中 Cell 类加了 @sun.misc.Contended 注解,每个 Cell 占用独立缓存行(通常 64 字节),避免多核 CPU 下因伪共享(false sharing)导致的频繁缓存同步。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
AtomicLong 的 value 虽是 volatile,但若和邻近字段共处同一缓存行,其他字段被修改也会引发整行失效——LongAdder 从结构上规避了这点。
性能差异随并发规模放大
这不是常量级优化,而是竞争越激烈,优势越明显:
- ≤4 线程(接近 CPU 物理核心数):AtomicLong 快约 20%~30%,LongAdder 首次竞争有 probe 初始化开销
- ≥8 线程:LongAdder 吞吐量开始反超,实测可达 AtomicLong 的 4.9 倍(16 线程)至 56 倍(64 线程)
- 关键原因:CAS 失败率断崖下降,线程从“死磕一个地址”变成“各干各的”,CPU 时间真正花在累加上,而非空转
代价与适用边界要清楚
高性能是以空间换时间,并接受语义妥协:
- 内存更高:cells 数组最多分配 CPU 核心数个 Cell 对象,每个含 long + padding,比 AtomicLong 多几 KB 到几十 KB
-
读非强一致:
sum()遍历所有 cells 并加 base,是最终一致性快照,不保证某时刻的精确瞬时值 -
不支持条件更新:没有
compareAndSet(),无法做“大于某值才执行”的逻辑 - reset() 非线程安全:仅适合无写入时归零,否则可能丢更新
所以它只适合写多读少、允许最终一致的场景,比如 QPS 统计、错误计数、耗时累加——不是所有“要加数字”的地方都该换。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










