乐观锁:CAS

一、CAS 简述

CAS:比较并交换(CompareAndSwap),应用于多线程并发场景中,实现了无锁状态下的线程安全。CAS 避免了使用互斥锁,当多个线程同时进行 CAS 指令更新同一个变量时,只有其中一个线程能够操作成功,而其他线程都会更新失败。但此时更新失败的线程并不会被阻塞,而是还可以再次 CAS 尝试。

二、Unsafe 类

sun.misc.Unsafe 是 Java 提供的一个可直接操作内存空间的类。其特点:

1)、不受 JVM 管理,使用 Unsafe 操作内存无法被 JVM GC,需要手动 GC,此时容易出现内存泄漏。

2)、Unsafe 的很多方法必须提供原始地址(内存地址)和 被替换对象的地址,偏移量要自己计算(其提供的有计算偏移量的方法),如果出现问题将会导致整个JVM 实例崩溃。

3)、直接操作内存,所以速度更快,在高并发的条件之下能够很好地提高效率。

Unsafe 类中有大量的被 native 关键字修饰的方法,这些方法是由 C/C++ 实现,底层调的是 C/C++ 的库函数,还有一些基于 native 方法封装的其他方法,整个Unsafe中的方法大致可以归结为以下几类:初始化操作、操作对象属性、操作数组元素、线程挂起和恢复和 CAS 机制。

Unsafe 类中的 compareAndSwap方法:

    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);

 

三、CAS 原理

CAS 有三个操作数:内存值 V、预期值 A、要修改的值 B。仅当预期值 A 和当前的内存值 V 相同时,才将内存值修改为 B ,否则什么都不做。

1)、Unsafe 类中的所在方法都是native修饰的,也就是送 Unsafe 类中的方法都直接调用操作系统底层资源执行相应任务,故可以直接比较内存值和期望值。value 值被 volatile 修饰后保证了其可见性,一旦发生偏移就会通知本地内存。

2)、变量 valueOffset ,表示该变量值在内存中的偏移地址,因为 Unsafe 就是根据内存偏移地址获取数据的。

3)、变量value 用 volatile修饰,保证了多线程之间内存的可见性

    /**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

 

 /*
    var1 Atomiclntegler对象本身。
    var2该对象值得引用地址。
    var4 需要变动的数量。
    var5是用过var1 var2找出的主内存中真实的值。
    用该对象当前的值与var5比较:
    如果相同,更新var5+var4并且返回true,如果不同,继续取值然后再比较,直到更新完成。
*/
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

compareAndSwapInt 的 JNI 本地实现代码:

CAS 缺点:

1)、循环时间长开销很大,unsafe 底层如果不匹配成功会一直 do-while 下去(如下图代码),一直不成功会造成很大的 cpu 开销)

2)、只能保证一个共享变量的原子操作。(一次只能保证一个对象)

3)、可能产生ABA问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值