zoukankan      html  css  js  c++  java
  • 原子类的 ABA 问题

    原子引用

    public class AtomicReferenceDemo {
        public static void main(String[] args) {
            User cuzz = new User("cuzz", 18);
            User faker = new User("faker", 20);
            AtomicReference<User> atomicReference = new AtomicReference<>();
            atomicReference.set(cuzz);
            System.out.println(atomicReference.compareAndSet(cuzz, faker)); // true
            System.out.println(atomicReference.get()); // User(userName=faker, age=20)
        }
    }

    ABA问题的产生

    /**
     * 当有一个值从 A 改为 B 又改为 A,这就是 ABA 问题
     **/
    public class ABADemo {
        private static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    
        public static void main(String[] args) {
            new Thread(() -> {
                atomicReference.compareAndSet(100, 101);
                atomicReference.compareAndSet(101, 100);
            }).start();
    
            new Thread(() -> {
                // 保证上面线程先执行
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                atomicReference.compareAndSet(100, 2019);
                System.out.println(atomicReference.get()); // 2019
            }).start();
        }
    }

    时间戳原子引用

    /**
     * 我们先保证两个线程的初始版本为一致,后面修改是由于版本不一样就会修改失败
     **/
    public class ABADemo2 {
        private static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);
    
        public static void main(String[] args) {
            new Thread(() -> {
                int stamp = atomicStampedReference.getStamp();
                System.out.println(Thread.currentThread().getName() + " 的版本号为:" + stamp);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1 );
                atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1 );
            }).start();
    
            new Thread(() -> {
                int stamp = atomicStampedReference.getStamp();
                System.out.println(Thread.currentThread().getName() + " 的版本号为:" + stamp);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean b = atomicStampedReference.compareAndSet(100, 2019, stamp, stamp + 1);
                System.out.println(b); // false
                System.out.println(atomicStampedReference.getReference()); // 100
            }).start();
        }
    }
  • 相关阅读:
    51nod1363-最小公倍数之和
    [模板] 数论题的一些经验
    WC2019游记 && 课件
    (伪)WC2019题解
    [模板] 后缀自动机&&后缀树
    [模板] 二分图博弈 && BZOJ2463:[中山市选2009]谁能赢呢?
    界面修改日志
    [模板] dp套dp && bzoj5336: [TJOI2018]party
    BZOJ1025:[SCOI2009]游戏
    [模板] BSGS/扩展BSGS
  • 原文地址:https://www.cnblogs.com/ding-dang/p/13151223.html
Copyright © 2011-2022 走看看