乐观锁的缺点!~

ABA 问题是乐观锁一个常见的问题!

 

ABA 问题

如果一个变量 V 初次读取的时候是 A 值,并且在准备赋值的时候检查到它仍然 是 A 值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能
的,因为在这段时间它的值可能被改为其他值,然后又改回 A,那 CAS 操作就 会误认为它从来没有被修改过。这个问题被称为 CAS 操作的 “ABA”问题。

JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的 compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是

否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为
给定的更新值。

循环时间长开销大

自旋 CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给 CPU 带来非常大的执行开销。 如果 JVM 能支持处理器提供的 pause 指令那么 效率会有一定的提升,pause 指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使 CPU 不会消耗过多的执行资源,延迟的时间取决于具体 实现的版本,在一些处理器上延迟时间是零。

第二它可以避免在退出循环的时 候因内存顺序冲突(memory order violation)而引起 CPU 流水线被清空(CPU pipeline flush),从而提高 CPU 的执行效率。

 

只能保证一个共享变量的原子操作

CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。但是

从 JDK 1.5 开始,提供了 AtomicReference 类来保证引用对象之间的原子性,你

可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利 用 AtomicReference 类把多个共享变量合并成一个共享变量来操作。

回复

我来回复
  • 暂无回复内容

免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部