JAVA面试-并发篇 07-CAS底层原理是什么有什么缺陷如何解决

CAS底层原理、缺陷及解决方案

一、文章概述

CAS(Compare And Swap,比较并交换)是Java无锁并发编程的核心原子操作,基于CPU底层原语实现,无需加锁即可保证线程安全,是JUC原子类、AQS同步器的核心基石。本文通俗讲解CAS的底层执行原理、三大核心缺陷,以及对应的解决方案。

二、CAS底层原理

CAS包含内存值V、预期值A、新值B三个核心参数,执行逻辑为原子性比较与替换:

  1. 读取共享变量的内存值V
  2. 对比V与预期值A是否相等
  3. 相等则将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资源
单变量限制 仅支持单个共享变量的原子操作,无法批量操作

四、缺陷解决方案

  1. ABA问题 :添加版本号/时间戳 标记,每次修改变更版本,使用AtomicStampedReference类解决
  2. 自旋开销 :JDK采用自适应自旋,限制自旋次数,避免CPU空转
  3. 多变量操作:使用AtomicReference封装对象,实现多变量组合的原子操作

总结

CAS通过CPU原子指令实现无锁并发,性能远超重量级锁。其存在的ABA、自旋开销、单变量限制三大缺陷,均可通过版本号、自适应自旋、对象封装等方案完美解决,是Java高并发场景中最核心的无锁技术。

相关推荐
青石路2 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
kyriewen2 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
她的男孩4 小时前
后台接口加密别只会 HTTPS,ForgeAdmin 的 RSA + SM4/AES 源码拆解
后端·面试·开源
Randyliu4 小时前
20260508-Agent搭建记录以及对ReAct框架的理解
面试·agent
像我这样帅的人丶你还5 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
ZzT5 小时前
公司用 AI 筛简历,他写了个 AI 帮你挑公司
面试·aigc·ai编程
PBitW6 小时前
GPT训练我的第四天,被打惨了!!!😭😭😭
前端·javascript·面试
plainGeekDev7 小时前
GreenDAO → Room
android·java·kotlin
云技纵横11 小时前
@Transactional 到底要不要加 rollbackFor?一次数据不一致事故讲清楚
后端·面试
Moment11 小时前
牛逼,NextJs 从 16.3 开始全面拥抱 Agent Native 🥰🥰🥰
前端·后端·面试