大厂面试真题-CAS的弊端和规避措施

CAS 操作的弊端和规避措施

1. CAS 操作的弊端

CAS 操作的弊端主要有以下 4 点。

1ABA问题

使用 CAS 操作内存数据时,当数据发生过变化也能更新成功,如操作序列 A==>B==>A 时,最
后一个 CAS 的预期数据 A 实际已经发生过更改,但也能更新成功,这就产生了 ABA 问题。
ABA 问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候将版
本号加 1 ,那么操作序列 A==>B==>A 的就会变成 A1==>B2==>A3 ,如果将 A1 当作 A3 的预期数据,
就会操作失败。
JDK 提供了两个类 AtomicStampedReference AtomicMarkableReference 来解决 ABA 问题。比较
常用的是 AtomicStampedReference 类,该类的 compareAndSet 方法的作用是首先检查当前引用是否等
于预期引用,以及当前印戳是否等于预期印戳,如果全部相等,就以原子方式将引用和印戳的值一
同设置为新的值。

2)只能保证一个共享变量之间的原子性操作

当对一个共享变量执行操作时,我们可以使用循环 CAS 的方式来保证原子操作,但是对多个
共享变量操作时, CAS 无法保证操作的原子性。
一个比较简单的规避方法为:把多个共享变量合并成一个共享变量来操作。
JDK 提供了 AtomicReference 类来保证引用对象之间的原子性,可以把多个变量放在一个
AtomicReference 实例后再进行 CAS 操作。比如有两个共享变量 i 1 j=2 ,可以将二者合并成一个
对象,然后用 CAS 来操作该合并对象的 AtomicReference 引用。

3)无效CAS会带来开销问题

自旋 CAS 如果长时间不成功(不成功就一直循环执行,直到成功为止),就会给 CPU 带来非
常大的执行开销。

4)在部分CPU平台上存在“总线风暴”问题

CAS 操作和 volatile 一样也需要 CPU 进行通过 MESI 协议各个内核的“ Cache 一致性”,会通过
CPU BUS (总线)发送大量 MESI 协议相关的消息,产生“ Cache 一致性流量”。因为总线被设计
为固定的“通信能力”,如果 Cache 一致性流量过大,总线将成为瓶颈,这就是所谓的“总线风暴”。

2. 提升 CAS 性能

提升 CAS 性能有效方式之一是以空间换时间,分散竞争热点。较为常见的方案为:
1 )分散操作热点,使用 LongAdder 替代基础原子类 AtomicLong LongAdder 将单个 CAS 热点
value 值)分散到一个 cells 数组中。
2 )使用队列削峰,将发生 CAS 争用的线程加入一个队列中排队,降低 CAS 争用的激烈程度。
JUC 中非常重要的基础类 AQS (抽象队列同步器)就是这么做的。
提升 CAS 性能有效方式之二是使用线程本地变量,从根本上避免竞争。
声明:本文来源于网络
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值