longadder通过分段cas提升高并发计数性能:以base值应对低并发,以cells数组分散线程到不同cell执行独立cas,结合probe哈希定位、@contended防伪共享及动态扩容机制,实现写竞争打散与读操作无锁化。

LongAdder 不是“绕开 CAS”,而是把 CAS 拆到多个独立内存地址上运行——用空间换时间,让高并发下的计数不再挤在同一个变量上死磕。
分段结构:base + cells 数组
LongAdder 内部维持两个部分:
- base:一个基础 long 值,低并发时直接用 CAS 更新它,轻量高效
- cells 数组:动态扩容的 Cell 对象数组,每个 Cell 包含一个 volatile long value,对应独立内存地址
所有线程不共用一个 CAS 目标,而是各自找“自己的槽位”更新,天然避开单点争抢。
线程如何定位自己的 Cell
每个线程通过自身 probe 值(来自 ThreadLocalRandom)哈希计算索引,再用位运算快速映射到 cells 数组下标:
- probe 值每次 CAS 失败后会调用 advanceProbe() 更新,避免哈希冲突固化
- 映射结果尽量均匀分散,使线程大概率落在不同 Cell 上
- Cell 对象本身用 @Contended 注解隔离,防止缓存行伪共享
CAS 分散执行与失败转移机制
线程不是在一个地址上无限自旋,而是一套“尝试—转移—扩容”的协作流程:
- 先尝试 CAS 更新 base,失败则进入分段逻辑
- 定位到某个 Cell 后,对该 Cell.value 执行 CAS;若为空或失败,不硬等,而是重新 probe、换槽位重试
- 当多个线程反复失败,首个感知到严重竞争的线程触发 cells 扩容(2 的幂次增长),后续线程自动分流
读操作不参与竞争:sum() 是纯遍历
获取总数时,LongAdder 不做任何 CAS 或锁操作:
- 直接读取 base 值
- 遍历所有非空 Cell,累加它们的 value 字段
- 整个过程无同步、无写冲突,但结果是最终一致的(非强实时)
这种设计把写竞争彻底打散,又让读操作完全脱离竞争路径,是性能跃升的关键所在。











