LongAdder 通过 base + cells 双层结构实现高并发写分流:低并发时仅用 base(同 AtomicLong),竞争时懒初始化 cells 数组,线程按哈希固定槽位写入独立 Cell,避免伪共享;冲突时 rehash 或退至 base;扩容倍增且非强制;sum() 遍历累加 base 与所有 Cell,结果为近似值。

用 base + cells 双层结构分流写请求
LongAdder 不是靠更强的原子性,而是把“所有人挤一个门”改成“多扇门分流”。它内部维护一个 base 字段(初始值)和一个可选的 Cell[] 数组。低并发时所有线程都走 base,行为和 AtomicLong 完全一致,零额外开销;一旦出现 CAS 失败(说明有竞争),才懒初始化 cells 数组,默认长度为 2。
线程按哈希固定槽位,尽量不碰别人的数据
每个线程通过自己的 threadLocalProbe 值计算哈希,再用位运算 hash & (cells.length - 1) 快速定位到某个 Cell 槽位。同一线程后续操作会复用同一槽位,不同线程大概率落在不同槽位——相当于 Thread-1 写 cells[3],Thread-2 写 cells[7],彼此互不干扰。
- Cell 是静态内部类,每个实例只持有一个 volatile long value
- 加了
@Contended注解,强制每个 Cell 占满一个缓存行(64 字节),彻底避免伪共享 - 数组长度始终是 2 的幂,位运算替代取模,性能更稳
冲突时灵活应对,不卡死也不强等
如果线程发现目标 Cell 正被占用(CAS 失败),它不会原地自旋死磕,而是尝试 rehash 到其他槽位,或退回到 base 累加。扩容也非即时触发:只有当多个线程反复冲突、当前 cells 非空且未在扩容中时,才尝试用 cellsBusy 自旋锁 + CAS 双重检查后扩容。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 扩容是倍增(2→4→8…),上限一般不超过 CPU 核心数
- 扩容期间新来的 add 操作可能直接写 base,也可能协助迁移旧 Cell
- 扩容失败不抛异常、不阻塞,下次再试——这是“尽力而为”的设计哲学
读操作不参与竞争,但要接受近似结果
sum() 和 get() 都是遍历所有 Cell.value 并加上 base,全程无锁、不阻塞写入。这意味着:
立即学习“Java免费学习笔记(深入)”;
- 读不是 O(1),耗时随 cells.length 线性增长
- 遍历时其他线程可能正在修改某些 Cell,结果是“尽力聚合后的近似和”
- 刚扩容出的新 Cell 若还没赋值,sum() 可能漏掉(value=0),属于设计允许的误差

















