CAS介绍

作者: 一直在路上_求名 | 来源:发表于2019-03-25 23:48 被阅读0次

    什么是CAS

    CAS的全称是Compare And Swap 即比较和交换的意思,其实现过程由名称可知,其包括两个部分,第一需要先比较,比较通过后然后再交换;看起来这是两步操作,但是由于底层硬件的支持,使两步操作能一步完成,从而保证了原子性,避免了独占锁的资源浪费。

    CAS核心算法

    核心函数:compareAndSwap(V,E,N)
    

    V:表示当前变量在主内存中的实际值;
    E:表示当前变量在当前工作线程中内存的实际值;
    N:表示当前变量需要被更新的值;
    如果V的值和E的值相同则将V的值替换为N,如果不相等则什么都不做,但是此时线程并不会退出,会继续进行比较,直到某次成功为止;
    这里特别需要理解的是V和E这两个值,由于Java的内存模型,所以V是当前变量在主内存中的实际值,E则是当前变量在当前工作线程中内存的实际值,只有当前线程中的数值和主存中相同,则将V替换为N刷新主存;
    还有一点需要注意的是,CAS能保证原子性和线程的互斥性,并不能保证可见性,所以,使用CAS的变量必须使用volatile修饰,从而保证可见性,这样就即保证了原子性和互斥性又保证了可见性;

    Java中CAS的实现

    在java中是使用Unsafe类来实现的CAS算法,其包括一下三个方法:

    public final native boolean compareAndSwapObject(Object var1, long var2, Object var3, Object var4);
    public final native boolean compareAndSwapInt(Object var1, long var2, int var3, int var4);
     public final native boolean compareAndSwapLong(Object var1, long var2, long var3 long var4);
    

    这三个方法入参都基本一样
    var1:表示要修改的变量所在的对象地址引用;
    var2:表示要修改的变量的内存偏移量;
    var3:表示要修改的变量在当前线程中的数值;
    var4:表示要修改的变量,需要被更新的新值;
    由var1和var2能获取到当前变量在主存中的数值,从而再和当前线程中的数值var3比较,进行CAS操作;
    从方法可知,这几个方法都是native方法,是调用底层的方法,从而依靠硬件实现的CAS;

    CAS的缺点

    CAS依靠底层硬件操作,从而保证了独占锁对资源的浪费,是一个非常好的方式;但是其也有自己的缺点;
    如果一个变量V从当前线程读取的时候是A,在主存中读取的时候也仍然是A值,这个时候CAS就会给变量赋新值,但是并不能保证在这个过程中改变量没有被修改过,如果在某段时间它的值曾经被改成了B,然后又改回A,那CAS操作就会认为它从来没有被修改过,这就是著名的ABA的问题了。
    但是这个问题在通常情况下并不会影响程序并发修改的正确性,因此不需要太关注,如果需要防止ABA问题的发生,就需要使用传统的互斥锁来解决了。

    相关文章

      网友评论

          本文标题:CAS介绍

          本文链接:https://www.haomeiwen.com/subject/uwgivqtx.html