CAS机制通过无锁、细粒度、快慢路径分离等设计提升并发容器吞吐量:避免阻塞与上下文切换,读操作零开销,写操作按冲突程度选择CAS或桶级锁,并支持延迟初始化与分段计数。

CAS 机制在无锁并发容器中提升吞吐量,核心在于避免线程阻塞、减少上下文切换、把同步开销压到最低——它不靠“排队等锁”,而是让线程快速尝试、失败即重试,多数操作在一次原子指令内完成。
消除阻塞,释放 CPU 并行能力
传统锁(如 synchronized 或 ReentrantLock)一旦争抢激烈,线程会挂起进入阻塞态,触发操作系统调度,带来上下文切换开销。CAS 完全运行在用户态:线程始终活跃,只是不断比对并更新值。尤其在读多写少或冲突率低的场景下,绝大多数 CAS 操作一次成功,没有停顿、没有唤醒延迟。
- ConcurrentHashMap 的 get() 操作全程无锁、无 CAS,纯 volatile 读,零同步开销
- put() 在桶为空时直接 CAS 插入头节点,跳过加锁路径,平均耗时远低于加锁插入
- 多个线程同时向不同桶写入,彼此完全不干扰,吞吐随 CPU 核数近似线性增长
细粒度协作替代全局竞争
CAS 不是孤立使用的,它和数据结构设计深度绑定,把“锁的范围”压缩到单个内存位置:一个数组槽位、一个指针+版本号组合、甚至一个 long 的高低位。这种细粒度使并发容器能真正实现“各干各的”。
- 用 AtomicStampedReference 封装 tail 指针 + stamp,确保队列尾部推进时指针与状态代际严格一致,避免 ABA 和误更新
- 将计数器与版本号打包进一个 AtomicLong:低 32 位存 count,高 32 位存 version,每次更新都强制 version 自增,杜绝覆盖写和脏读
- 扩容时通过 CAS 更新 transferIndex 协调任务分片,每个线程领取一段桶独立迁移,无需协调锁
快慢路径分离,按需降级不硬扛
纯 CAS 并非万能。ConcurrentHashMap 等成熟容器的高吞吐,关键在于“该用 CAS 时坚决用,该加锁时不硬撑”。CAS 承担轻量、幂等、失败成本低的操作;一旦涉及结构变更(如链表尾插、树化、节点遍历),立刻退到桶级 synchronized——只锁一个 Node,不影响其他桶。
立即学习“Java免费学习笔记(深入)”;
- 空桶插入 → CAS 成功,0 开销
- 非空链表尾插 → CAS 头节点失败 → 对首节点加 synchronized → 遍历插入 → 锁释放
- 红黑树操作 → 进入 TreeBin 内部,用 synchronized 保护整棵树,但仅限该桶
延迟初始化与无竞争启动
容器创建时不分配资源,首次 put 才用 CAS 初始化 table 数组。这不仅省内存,更消除了“构造即竞争”的风险:多个线程同时触发初始化时,只有一个能通过 CAS 设置 table,其余自动让出并重试,没有锁等待队列,也没有初始化失败重抛异常的开销。
- sizeCtl 初始为 0,CAS 设为 -1 表示“我来初始化”,失败者直接循环检查,直到 table 可用
- baseCount 计数器全程用 CAS 更新,配合 CounterCell 分段计数,在高并发写入时分散热点,避免单点瓶颈


















