当前位置:网站首页>ABA问题遇到过吗,详细说以下,如何避免ABA问题

ABA问题遇到过吗,详细说以下,如何避免ABA问题

2022-07-06 09:20:00 快醒醒鸭今天你编程了吗?

1、有两个线程同时修改一个变量的值,线程1、线程2,都更新变量值,将变量从A更新为B

2、首先线程1获得到CPU时间片,线程2由于某些原因原因发生等待,线程1进行比较更新,CAS
(CompareAndSwap),成功将变量的值从A更新到B

3、更新完毕后,恰好又有线程3进来想要把变量的值从B更新到A,线程3进行比较更新,成功将变量的值从B更新为A

4、线程2获得到CPU时间片,然后进行比较更新,发现值是预期的A,然后又更新成了B,但是线程1并不知道该值已经从A-->B-->A这个过程,这就是ABA问题。

 

如何避免ABA问题?

可以通过加版本号或者时间戳解决,或者保证单向递增或递减就不会存在此类问题,atomic包下的AtomicStampedReference类的CompareAndSet方法首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该标志的值设置给定的更新值

package com.ws.cas;

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {

    //CAS compareAndSet:比较并交换!!!
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        //对于我们平时写的SQL来说:乐观锁!
        //第一个参数是期望、第二个参数是更新
        //public final boolean compareAndSet(int expect, int update)
        //如果我期望的值达到了,那么就更新,否则就不更新 CAS是CPU的并发原语


        //乱搞线程
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());

        System.out.println(atomicInteger.compareAndSet(2021, 2020));
        System.out.println(atomicInteger.get());

        //期望的线程
        System.out.println(atomicInteger.compareAndSet(2020, 6666));
        System.out.println(atomicInteger.get());



    }
}

CAS导致的其他问题?

  1. 只能保证一个共享变量的原子操作
  2. 自旋CAS如果长时间不成功,会给CPU带来开销大的问题
原网站

版权声明
本文为[快醒醒鸭今天你编程了吗?]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_46624528/article/details/124956490