CAS底层原理、缺陷及解决方案
一、文章概述
CAS(Compare And Swap,比较并交换)是Java无锁并发编程的核心原子操作,基于CPU底层原语实现,无需加锁即可保证线程安全,是JUC原子类、AQS同步器的核心基石。本文通俗讲解CAS的底层执行原理、三大核心缺陷,以及对应的解决方案。
二、CAS底层原理
CAS包含内存值V、预期值A、新值B三个核心参数,执行逻辑为原子性比较与替换:
- 读取共享变量的内存值V
- 对比V与预期值A是否相等
- 相等则将V更新为新值B,不相等则放弃更新
全程依赖CPU指令实现原子性,无线程切换开销。
#mermaid-svg-OUMlhiA6je2u2GjF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OUMlhiA6je2u2GjF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OUMlhiA6je2u2GjF .error-icon{fill:#552222;}#mermaid-svg-OUMlhiA6je2u2GjF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OUMlhiA6je2u2GjF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OUMlhiA6je2u2GjF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OUMlhiA6je2u2GjF .marker.cross{stroke:#333333;}#mermaid-svg-OUMlhiA6je2u2GjF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OUMlhiA6je2u2GjF p{margin:0;}#mermaid-svg-OUMlhiA6je2u2GjF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OUMlhiA6je2u2GjF .cluster-label text{fill:#333;}#mermaid-svg-OUMlhiA6je2u2GjF .cluster-label span{color:#333;}#mermaid-svg-OUMlhiA6je2u2GjF .cluster-label span p{background-color:transparent;}#mermaid-svg-OUMlhiA6je2u2GjF .label text,#mermaid-svg-OUMlhiA6je2u2GjF span{fill:#333;color:#333;}#mermaid-svg-OUMlhiA6je2u2GjF .node rect,#mermaid-svg-OUMlhiA6je2u2GjF .node circle,#mermaid-svg-OUMlhiA6je2u2GjF .node ellipse,#mermaid-svg-OUMlhiA6je2u2GjF .node polygon,#mermaid-svg-OUMlhiA6je2u2GjF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OUMlhiA6je2u2GjF .rough-node .label text,#mermaid-svg-OUMlhiA6je2u2GjF .node .label text,#mermaid-svg-OUMlhiA6je2u2GjF .image-shape .label,#mermaid-svg-OUMlhiA6je2u2GjF .icon-shape .label{text-anchor:middle;}#mermaid-svg-OUMlhiA6je2u2GjF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OUMlhiA6je2u2GjF .rough-node .label,#mermaid-svg-OUMlhiA6je2u2GjF .node .label,#mermaid-svg-OUMlhiA6je2u2GjF .image-shape .label,#mermaid-svg-OUMlhiA6je2u2GjF .icon-shape .label{text-align:center;}#mermaid-svg-OUMlhiA6je2u2GjF .node.clickable{cursor:pointer;}#mermaid-svg-OUMlhiA6je2u2GjF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OUMlhiA6je2u2GjF .arrowheadPath{fill:#333333;}#mermaid-svg-OUMlhiA6je2u2GjF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OUMlhiA6je2u2GjF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OUMlhiA6je2u2GjF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OUMlhiA6je2u2GjF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OUMlhiA6je2u2GjF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OUMlhiA6je2u2GjF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OUMlhiA6je2u2GjF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OUMlhiA6je2u2GjF .cluster text{fill:#333;}#mermaid-svg-OUMlhiA6je2u2GjF .cluster span{color:#333;}#mermaid-svg-OUMlhiA6je2u2GjF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OUMlhiA6je2u2GjF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OUMlhiA6je2u2GjF rect.text{fill:none;stroke-width:0;}#mermaid-svg-OUMlhiA6je2u2GjF .icon-shape,#mermaid-svg-OUMlhiA6je2u2GjF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OUMlhiA6je2u2GjF .icon-shape p,#mermaid-svg-OUMlhiA6je2u2GjF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OUMlhiA6je2u2GjF .icon-shape .label rect,#mermaid-svg-OUMlhiA6je2u2GjF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OUMlhiA6je2u2GjF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OUMlhiA6je2u2GjF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OUMlhiA6je2u2GjF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
读取内存值V
传入预期值A+新值B
V == A ?
原子更新为B
不更新,返回失败
三、CAS三大缺陷
| 缺陷类型 | 核心问题描述 |
|---|---|
| ABA问题 | 变量值从A→B→A,CAS无法感知中间变化,误判为未修改 |
| 自旋开销 | 高并发下CAS频繁失败,循环自旋占用大量CPU资源 |
| 单变量限制 | 仅支持单个共享变量的原子操作,无法批量操作 |
四、缺陷解决方案
- ABA问题 :添加版本号/时间戳 标记,每次修改变更版本,使用
AtomicStampedReference类解决 - 自旋开销 :JDK采用自适应自旋,限制自旋次数,避免CPU空转
- 多变量操作:使用
AtomicReference封装对象,实现多变量组合的原子操作
总结
CAS通过CPU原子指令实现无锁并发,性能远超重量级锁。其存在的ABA、自旋开销、单变量限制三大缺陷,均可通过版本号、自适应自旋、对象封装等方案完美解决,是Java高并发场景中最核心的无锁技术。