当前位置: 首页 > ops >正文

Java高频面试之并发编程-24

hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶

面试官:什么是CAS

CAS(Compare and Swap,比较并交换) 是一种 无锁(Lock-Free) 的原子操作机制,用于实现多线程环境下对共享变量的安全更新。其核心思想是“先检查再修改”,通过硬件指令(如 CPU 的 CMPXCHG)保证操作的原子性,避免使用传统锁机制带来的性能开销。


CAS 的核心原理

CAS 操作包含三个参数:

  • 内存地址(V):需要修改的共享变量的内存地址。
  • 期望值(A):该变量当前应具备的值(用于判断是否被其他线程修改过)。
  • 新值(B):希望将该变量更新为的值。

执行流程

  1. 比较:检查内存地址 V 中的当前值是否等于 A
  2. 交换
    • 若相等,说明变量未被其他线程修改,将 V 的值更新为 B,返回 true
    • 若不相等,说明变量已被其他线程修改,放弃更新,返回 false

整个过程由 硬件指令 保证原子性,不会出现中间状态。


CAS 的伪代码

function CAS(V, A, B) -> bool {if *V == A {*V = Breturn true} else {return false}
}

CAS 的典型应用场景

1. 原子类(如 AtomicInteger

Java 中的 AtomicInteger 使用 CAS 实现线程安全的数值操作:

AtomicInteger count = new AtomicInteger(0);// 线程安全的自增操作(底层基于 CAS)
count.incrementAndGet(); 
2. 无锁数据结构
  • 无锁队列无锁栈:通过 CAS 实现并发环境下的高效插入和删除。
  • 自旋锁(SpinLock):线程通过 CAS 循环尝试获取锁,避免线程阻塞。
3. 并发工具
  • ReentrantLock 的 AQS 内部通过 CAS 管理同步队列的入队和出队。
  • ConcurrentHashMap 在 JDK 8+ 中利用 CAS 优化桶节点的插入。

CAS 的优缺点

优点缺点
无锁设计,减少线程阻塞和上下文切换自旋开销:竞争激烈时循环重试可能浪费 CPU 资源
高并发场景下性能优于传统锁ABA 问题:变量可能被其他线程修改后又恢复原值,导致误判
避免死锁风险仅适用于简单操作,复杂逻辑需结合其他机制

CAS 的 ABA 问题

问题描述
  • 线程 1 读取变量值为 A
  • 线程 2 将变量从 A 修改为 B,再修改回 A
  • 线程 1 执行 CAS 时,误认为变量未被修改过,导致逻辑错误。
解决方案
  • 版本号标记:每次修改变量时递增版本号,CAS 同时检查值和版本号。
  • Java 实现:使用 AtomicStampedReferenceAtomicMarkableReference
AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(100, 0);// 更新时检查值 + 版本号
int stamp = ref.getStamp();
ref.compareAndSet(100, 200, stamp, stamp + 1);

CAS 的底层实现

  • 硬件支持:现代 CPU 提供 CMPXCHG 指令(如 x86 架构),操作系统或 JVM 将其封装为原子操作。
  • Java 中的实现:通过 sun.misc.Unsafe 类的 compareAndSwapIntcompareAndSwapLong 等本地方法调用硬件指令。

CAS 与锁的对比

特性CAS传统锁(如 synchronized
并发策略乐观锁(假设无冲突,冲突时重试)悲观锁(假设有冲突,直接阻塞)
线程阻塞无(自旋等待)有(线程进入阻塞状态)
适用场景低竞争、简单操作(如计数器)高竞争、复杂临界区
性能高并发下更高效竞争激烈时上下文切换开销大

你想要的技术资料我全都有:https://pan.q删掉汉子uark.cn/s/aa7f2473c65b

在这里插入图片描述

http://www.xdnf.cn/news/12818.html

相关文章:

  • Semantic-SAM: Segment and Recognize Anything at Any Granularity
  • 大模型如何选型?嵌入模型如何选型?
  • 【PhysUnits】17.2 配套变量结构体 Var(variable.rs)
  • 一套个人知识储备库构建方案
  • UE的AI行为树Selector和Sequence如何理解
  • 数据结构——D/串
  • comfyui 工作流中 图生视频 如何增加视频的长度到5秒
  • C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
  • Vivado软件开发流程操作详解
  • 五年级数学知识边界总结思考-下册
  • 【会员专享数据】1980—2022年中国逐日月年潜在蒸散发栅格数据
  • JavaScript 数组学习总结
  • Spyglass:跨时钟域同步(时钟门控单元)
  • eBPF系列--BCC中提供的BPF maps高级抽象如何映射到内核的BPF maps?
  • 【Ragflow】27.RagflowPlus(v0.4.1):小版本迭代,问题修复与功能优化
  • 比较一组结构之间的变换
  • Python爬虫实战:研究PySocks库相关技术
  • Halcon案例(三):C#联合Halcon识别排线
  • 【整数逐位除法求余补〇完整版】2022-4-11
  • 1 Studying《Linux Media Documentation》
  • 深度学习模块缝合
  • 【redis】线程IO模型
  • 第16届蓝桥杯青少Stema11月 Scratch编程——初/中级组真题——行走的图形
  • GD图像处理与SESSiON
  • MySQL(63)如何进行数据库读写分离?
  • 进程与线程的区别
  • SQL Server从入门到项目实践(超值版)读书笔记 16
  • Linux多线程-进阶
  • 设计模式学习
  • AtCoder Beginner Contest 409