CAS原理——乐观锁机制

CAS原理——乐观锁机制

一:CAS原理

乐观锁的本质即是CAS,操作系统提供了支持CAS修改内存值的原子指令,所以乐观锁得以实现。

CAS(CompareAndSwap)比较和替换(CPU级别的指令操作):通俗的理解就是 CAS 操作需要我们提供一个预期值,当预期值与当前线程的变量值相同时,说明还没线程修改该值,当前线程可以进行修改,也就是执行 CAS 操作。但如果预期值与当前线程不符,则说明该值已被其他线程修改,此时不执行更新操作。但可以选择重新读取该变量尝试再次修改该变量(自旋),也可以放弃操作。(自旋的次数实际上可以通过启动参数来配置,如果你不配置的话,默认是10,所以不会出现死循环)

那么我们会发现基于这个CAS原理,在并发量很高的情况下很容易就会比较失败。所以基于CAS的原子类并不适用于任何场景,在并发很高,竞争很激烈的情况下就不适合再使用了,可以考虑加锁或其它的方式来解决。)

CAS底层实现:sun.misc.Unsafe 这个类提供了如下3个CAS方法

/**
 * JDK源码
 */
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

obj 和 valueOffset:表示这个共享变量的内存地址。这个共享变量是obj对象的一个成员属性,valueOffset表示这个共享变量在obj类中的内存偏移量。所以通过这两个参数就可以直接在内存中修改和读取共享变量值。
expect: 表示预期原来的值。
update: 表示期待更新的值。

分析一下compareAndSwapInt()方法的四个参数:
var1代表AtomicInteger实例对象;
var2代表地址偏移量valueOffset (用来定位 value 在 AtomicInteger 对象中的位置);
var4代表预期值expect;
var5代表更新值update。

扩展:
为什么叫Unsafe类呢??
观察发现JUC中大量使用了sun.misc.Unsafe 这个类,但官方却不建议开发者使用

很显然方法都是用native来修饰的,这就表明这个方法不是由Java来实现的。而是调用底层的C或其他接口来实现的。所以由此可见CAS是一个CPU级别的指令操作。

其实Unsafe是用于在实质上扩展Java语言表达能力、便于在更高层(Java层)代码里实现原本要在更低层(C层)实现的核心库功能用的。这些功能包括裸内存的申请/释放/访问,低层硬件的atomic/volatile支持,创建未初始化对象等。它原本的设计就只应该被标准库使用。

建议看这个知乎帖子第一楼R大的回答:为什么JUC中大量使用了sun.misc.Unsafe 这个类,但官方却不建议开发者使用

二:ABA问题

如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。
在这里插入图片描述
ABA问题的解决思路就是使用版本号,在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A->B->A就会变成1A->2B->3A。

基于这种解决思路:
atomic包里提供了AtomicStampedReference和AtomicMarkableReference类来解决ABA问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小本科生debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值