• 【构建并发程序】4-原子变量-CAS-ABA问题


    原子变量中CAS的ABA问题


    原子变量的这种CAS看起来很爽,但是有可能会导致ABA问题。

    什么是ABA问题?

    简单点就是,3个线程对某个原子变量val inte = new AutoicInteger(1)进行操作

    • A线程要做inte.compareAndSet(1,2)
    • B线程要做inte.compareAndSet(1,3)
    • C线程要做inte.compareAndSet(3,1)
    1. A线程没抢过B,C两个线程,且BC两个线程中,B线程先执行的,然后是C线程,当C线程执行完后inte的内存地址已发生过两次偏移,新的地址值是1。
    2. A线程要做的是将inte的值变成2,当它从地址中进行读取的时候发现值是1正确,所以会赋值一个2,但是这里的inte地址已经不是当初新创建的那个地址了(因为内存地址发生过两次偏移);

    ABA问题会导致的后果

     ABA问题在只需要比对数值的这种情况下是没有问题的,例如查询库存量,然后进行相应的删除或修改。
    但在堆栈操作中就会出现问题了如下(假设有如下场景):

    1. 一个用单向链表实现的栈结构,栈顶元素为A。
    2. 这时线程1已经知道A.next为B,然后希望用CAS将栈顶替换为B;
      在这里插入图片描述
    3. 在线程1执行上面这条指令之前,线程2先得到执行,并且线程2将A、B两个元素依次出栈,再将D、C、A元素压入栈中。对象B此时处于游离状态,栈结构如下:
      在这里插入图片描述
    4. 此时轮到线程1进行CAS操作,检测发现栈顶仍然是A,所以CAS成功,栈顶元素变为B,但实际上B.next为null,所以此时的情况变为:栈中只有B一个元素,C和D不再存在于栈中,这样C和D元素就丢了。

    (本文章虽然采用的代码为scala代码,但java代码与Scala代码可以互相转换,且本质上两者所阐述的东西都是一致的)

  • 相关阅读:
    【C++ STL】-- deque与vector相比的优势与劣势
    hudi系列-借助hudi优化架构
    鸿蒙OS app开发环境搭建
    离散数学(十二):关系的幂运算与关系的性质
    【SpringBoot】一文了解SpringBoot配置高级
    拼多多按关键词搜索示例
    隧道测量快速坐标反程序48004850计算器
    Map获取其键和值
    浅析搭建高速公路视频监控平台的建设方案及必要性
    基于python的GUI设计
  • 原文地址:https://blog.csdn.net/qq_33982605/article/details/126689082