Striped64是抽象基类,不直接实例化,其核心价值在于通过base+Cell数组实现“多点分散”替代单点竞争,显著降低高并发下CAS自旋开销;子类LongAdder等实际用于高性能累加。

Java 中不直接使用 Striped64,它是抽象基类,不能实例化;真正用于高并发累加的是它的子类,比如 LongAdder 和 DoubleAdder。它的核心价值在于把“单点竞争”变成“多点分散”,从而显著降低 CAS 自旋开销。
为什么不用 AtomicInteger/AtomicLong?
在极高并发下,所有线程都争抢同一个 volatile 变量 + CAS,失败后不断重试,CPU 白耗、吞吐下降。这就像只有一台收银机,所有人排队——Striped64 的思路是:设多个收银台(Cell 数组),按线程哈希分配,让多数人各忙各的。
Striped64 是怎么分散竞争的?
它靠三个关键成员协同工作:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- base:一个 volatile long,无竞争时直接 CAS 更新,相当于“默认收银台”
-
cells 数组:大小为 2 的幂(如 2、4、8…),每个元素是
Cell对象,内部封装一个 volatile long + CAS 方法;线程通过getProbe()获取哈希值,再用(n - 1) & hash定位数组下标 - cellsBusy:自旋锁(0/1 标志),仅在初始化 cells、扩容或填充空 Cell 时使用,保护数组结构变更,不影响日常累加
实际使用推荐方式
直接用子类,写法简洁且语义清晰:
立即学习“Java免费学习笔记(深入)”;
- 计数场景 →
LongAdder adder = new LongAdder();,调用adder.increment()或adder.add(5) - 需要最终总和 →
adder.sum()(非原子快照,但误差极小;若需强一致性可考虑sumThenReset()) - 替代 AtomicLong 的升级路径:把
AtomicLong替换为LongAdder,其他逻辑基本不动 - 注意:它不适合做“判断+更新”类逻辑(如 if count > 100 then reset),因为 sum() 不是原子操作;这类需求仍需 AtomicLong 或显式锁
底层优化细节值得留意
这些设计让性能提升落到实处:
-
@sun.misc.Contended注解加在Cell类上,防止不同 Cell 实例落在同一 CPU 缓存行,避免伪共享(False Sharing) - 哈希值来自
ThreadLocalRandom.getProbe(),线程本地生成,无全局竞争 - 数组扩容是懒加载的:首次冲突才建 cells[2],后续按需翻倍,避免内存浪费
- 当某个 Cell 频繁冲突(collide=true),会尝试扩容或重新哈希,主动缓解热点


















