LongAdder基于Striped64实现分段CAS无锁设计,通过cell数组分散写竞争,牺牲强一致性换取高吞吐;Striped64为抽象基类,仅用CAS和volatile,不涉及任何锁机制。

LongAdder 并不是基于 Striped64 的分段锁,而是基于 Striped64 的分段 CAS(无锁)设计,其核心哲学是“空间换时间 + 热点分散”,而非锁的分段。
Striped64 是基础框架,不是锁机制
Striped64 是一个抽象基类,提供 cell 数组、base 值、以及用于竞争时扩容/初始化的伪随机 probe 值。它本身不实现任何锁逻辑,也不使用 synchronized 或 ReentrantLock。它的所有并发控制都依赖于 Unsafe.compareAndSwapLong(即 CAS)和 volatile 读写。
LongAdder 继承自 Striped64,复用其 cell 分片结构,但所有更新操作(如 add())全程无锁——仅在低竞争时直接 CAS base;高竞争时尝试 CAS 对应 cell,失败则重试或扩容 cell 数组。
LongAdder 放弃强一致性,换取高吞吐
与 AtomicLong 的严格顺序一致性不同,LongAdder 的 sum() 方法需遍历所有 cell 并累加 base,结果是最终一致、非实时精确值。这种设计允许:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 多个线程同时向不同 cell 写入,零冲突
- add() 操作几乎总能快速完成(通常一次 CAS 成功)
- sum() 虽然开销略大,但被限定为读多写少场景下的“代价可控”操作
对比 AtomicLong:不是锁 vs 锁,而是单点瓶颈 vs 并行热点
AtomicLong 的问题不在“用了锁”,而在所有线程争抢同一个 volatile long 变量——本质是单点 CAS 竞争瓶颈。而 LongAdder 通过 cell 数组把写压力分散到多个独立内存位置:
- 每个 cell 是独立的 volatile long,彼此无依赖
- 线程根据 thread-local probe 值哈希定位 cell,天然降低碰撞概率
- cell 数组可动态扩容(最多到 CPU 核心数),适配实际并发度
为什么不用分段锁?因为没必要且更重
如果真用分段锁(比如按 hash 分段加 synchronized 块),会引入:
- 锁对象创建与管理开销
- 线程阻塞与上下文切换风险
- 锁粒度难以平衡:太粗仍竞争,太细则锁表膨胀
而 Striped64 的 CAS 分片方案,在绝大多数场景下既避免了阻塞,又比锁更轻量——只要硬件支持原子 CAS(现代 CPU 全支持),就能跑起来。
本质上,LongAdder 的设计不是“把锁分段”,而是“把状态分片 + 用无锁方式更新”。它代表了一种典型的高性能并发编程取舍:牺牲瞬时精度,换取极高写吞吐和极低延迟。

















