ABA问题

ABA问题

问题现象:两个线程都去获取一个值,第一个线程获取后将其改变,然后又改回来,第二个线程获取到之后以为是第一个值,继续执行下去

ABA问题示例

package com.example.juc;

import java.util.concurrent.atomic.AtomicInteger;

public class TestCas {


    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(2021);
        int andIncrement = atomicInteger.getAndIncrement();
        System.out.println(atomicInteger.compareAndSet(2022, 2023));
        System.out.println(atomicInteger.compareAndSet(2023, 2022));
        System.out.println(atomicInteger);

        System.out.println(atomicInteger.compareAndSet(2022, 2022));
        System.out.println(atomicInteger);


    }
}
true
true
2022
true
2022

解决方案:带版本号的CAS

package com.example.juc;

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

public class TestAba {
    public static void main(String[] args) {
        Integer integer = 1;
        Integer integer1 = 2;
        AtomicStampedReference<Integer> iasr = new AtomicStampedReference<>(integer, 1);
        int stamp = iasr.getStamp();
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(iasr.compareAndSet(1, 2, iasr.getStamp(), iasr.getStamp() + 1));
            System.out.println(iasr.compareAndSet(2, 1, iasr.getStamp(), iasr.getStamp() + 1));

        }).start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(iasr.compareAndSet(1, 2, stamp, iasr.getStamp() + 1));

        }).start();
    }
}
true
false
true
posted @ 2021-12-23 15:34  Oh,mydream!  阅读(72)  评论(0编辑  收藏  举报