cas引出的ABA问题?如何解决?- 理解原子引用、时间戳(版本号)原子引用

ABA问题:

假如有两个线程1,2;
cas下:1.线程取值完等待,2线程取值并把A改成B,有把B改成A,这是1线程执行会任务A还是原来的A没有发生改变,如果不在乎中间结果,只看收尾,那么没必要解决ABA问题

如何解决?

使用AtomicStampedRefererce,加版本号

代码演示如下:

package Volatile;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * ABA问题的解决办法  AtomicStampedReference 时间戳原子引用·
 */
public class ABA {
    static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100,1);

    public static void main(String []args){
        System.out.println("==========以下是ABA问题的产生=======");
        new Thread(()->{
            atomicReference.compareAndSet(100,101);
            atomicReference.compareAndSet(101,100);
        },"t1").start();

        new Thread(()->{
            //暂停1秒t2线程,保证t1完成一次ABA
            try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace();}
            System.out.println(atomicReference.compareAndSet(100,2019)+"\t"+atomicReference.get());
        },"t2").start();

        try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace();}
        System.out.println("=========以下是ABA问题的解决==========");

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t第一次版本号:"+atomicStampedReference.getStamp());
            //暂停1秒t3线程,让t4也获取到一样的stamp
            try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace();}
            atomicStampedReference.compareAndSet(100,101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t第二次版本号:"+atomicStampedReference.getStamp());
            atomicStampedReference.compareAndSet(101,100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t第三次版本号:"+atomicStampedReference.getStamp());

        },"t3").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t第一次版本号:"+atomicStampedReference.getStamp());
            //暂停1秒t3线程
            try {TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace();}
            boolean result = atomicStampedReference.compareAndSet(100, 2019, stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName()+"\t修改功否:"+result);
            System.out.println(Thread.currentThread().getName()+"\t当前实际最新值:"+atomicStampedReference.getReference());
        },"t4").start();

    }
}

在这里插入图片描述

发布了83 篇原创文章 · 获赞 61 · 访问量 9180

猜你喜欢

转载自blog.csdn.net/weixin_43736084/article/details/103799452