zoukankan      html  css  js  c++  java
  • CAS中的ABA问题

    经典的ABA问题:

     ABA问题存在CAS无锁方案中,我们写一个CAS的伪代码栗子:

    class SimulatedCAS{
        volatile int    count;
        int newValue;
        //实count+=1
        addOne(){
             do    {
                  newValue=count+1;    //
            }while(count != cas(count,newValue)    )//
        }
        //模拟实现CAS,仅⽤来帮助理解
        synchronized int cas( int expect, int newValue){
            // 读⽬前count的值
            int    curValue=count;
            //    ⽐较⽬前count值是否==期望值
            if(curValue==expect){
            //    如果是,则更新count的值
                count=newValue;
            }
            //    返回写⼊前的值
            return    curValue;
        }
    
    }
    假设 count原本是 A,线程 T1 在执行完代码①处之后,执行代码②处之前,有可能 count 被线程 T2 更新成了 B,之后又被 T3 更新回了 A,这样线程 T1 虽然看到的一直是 A,但是这个值其实已经被其他线程更新过了,这就是 ABA 问题
     

    如何解决:

    最简单的方案就是给值加一个修改版本号,每次值变化,都会修改它版本号,CAS操作时都对比此版本号。

    Java中提供的原子化的对象引用类型AtomicStampedReferenceAtomicMarkableReference 这两个原子类可以解决 ABA 问题。
     
     1     public boolean compareAndSet(V   expectedReference, V   newReference,
     2                                  int expectedStamp, int newStamp) {
     3         Pair<V> current = pair; //获取当前pair
     4         return
     5                 expectedReference == current.reference && //原始值等于当前pair的值引用,说明值未变化
     6                 expectedStamp == current.stamp && // 原始标记版本等于当前pair的标记版本,说明标记未变化
     7                         
     8                 ((newReference == current.reference && newStamp == current.stamp) || // 将要更新的值和标记都没有变化
     9                         casPair(current, Pair.of(newReference, newStamp))); // cas 更新pair
    10     }
    ==========================================================================           如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞】,希望我们一起在架构的路上,并肩齐行
    ==========================================================================
  • 相关阅读:
    PyCharm配置 Git 教程
    Docker实践:基于python:3.7.1-stretch制作python镜像
    Docker开启远程安全访问
    Centos7安装apt-get
    Kubernetes 系列(二):在 Linux 部署多节点 Kubernetes 集群与 KubeSphere 容器平台
    微信小程序调试mock 数据,提示合法域名校验失败
    babel-plugin-import 配置多个组件按需加载时
    docker run -p 8070:80 -d nginx
    数据库的设计(E-R图,数据库模型图,三大范式)
    数据库 范式
  • 原文地址:https://www.cnblogs.com/amberJava/p/12390939.html
Copyright © 2011-2022 走看看