• CAS


    CAS

    CAS(Compare And Swap),是Java中的一种无锁优化,又被称作自旋锁或者乐观锁,而synchronized和ReentrantLock则是悲观锁的典型代表

    乐观锁:总是假设最好的情况,每次拿数据都认为别人不会修改数据,所以不会加锁,但是更新的时候,会判断在此期间有没有人修改过;一般基于版本号机制实现
    悲观锁:总是假设最坏的情况,每次拿数据都认为别人会修改数据,所以要加锁,别人只能等待,直到我释放锁之后别人才能拿到锁

    原子类

    在Java中的各种原子类的递增递减等方法都是使用的CAS机制保证的数据的原子操作,从而保证数据的一致性,最终调用的都是Unsafe类中的方法,这里拿AtomicInteger的incrementAndGet方法来做示例:

    //AtomicInteger中的incrementAndGet方法
    public final int incrementAndGet() {
        //因为Unsafe类中的getAndAddInt方法返回的都是期望值,也就是当前值,但此时已经内部完成了自增操作,所以这里需要对返回值进行加一后返回
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;   
    }
    
    //Unsafe中的getAndAddInt方法
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2); //从共享(堆)内存中获取期望值(当前值)
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//执行调用JNI方法(CAS)来完成操作,如果失败则循环执行
        return var5;    //返回期望值
    }
    

    CAS原理图


    CAS原理的伪代码如下所示

    CAS(Value,Except,NewValue)
        if Value==Except
            Value=NewValue
        otherwise try again or fail
    

    细心的朋友到这里可能会问,如果在一个线程判断完Value==Expect,但是未完成Value=NewValue时Expect被其他线程修改了怎么办?
    这里完全是不用担心的,这是受底层CPU支持的原子操作,一旦执行就不能被其他线程打断,即Value==Expect和Value=NewValue要么同时完成,要么同时失败

    ABA问题

    CAS是一种乐观锁,在运行过程中假定其他线程不会来修改数据,但在高并发的环境下,难免会遇到数据被修改的情况,如果数据被修改的和原来不一样了,那么没有关系,会被检测到重新获取一次期望值再次执行即可,但是如果数据被多次修改后最终变回原值,这对于一般的CAS就没法检测了,这就是ABA问题,当数据时基本类型时,该问题并无大碍,但如果数据时引用类型时就有可能出问题,该处假定一个场景:期望值为对象A,在其他线程中把期望值设置为B,并修改了B中的值,最后将期望值又设置为对象A,这时就可能会出现问题了
    解决方法:可以在期望值对象中增加一个版本号,每当其中的值被修改时,就将版本号加一,在CAS的判断中不止判断期望值的值,而且还要判断期望值的版本号从而规避ABA问题

    如果对你有帮助,点个赞,或者打个赏吧,嘿嘿
    整理不易,请尊重博主的劳动成果

  • 相关阅读:
    free online Twitter video downloader All In One
    Game Development Essential Terms All In One
    Offscreen Canvas All In One
    前端性能优化系列之 Service Workers 实战教程 All In One
    前端性能优化系列之 Web Workers 实战教程 All In One
    河南美食阿利茄汁面 All In One
    free online Youtube video downloader All In One
    Leetcode 2264. 字符串中最大的 3 位相同数字(可以,已解决)
    多分类任务中不同隐藏层层数对实验结果的影响(使用GPU)
    Pytorch 损失函数总结
  • 原文地址:https://www.cnblogs.com/Mango-Tree/p/12834441.html
Copyright © 2020-2023  润新知