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();
        }
    }
  • 相关阅读:
    java rmi 入门实例
    flex“深拷贝”
    Cygwin 下部署Hadoop
    Hadoop学习原地
    Scribe+HDFS日志收集系统安装方法
    使用HDFS来进行线上应用的文件存储
    转:C++初始化成员列表
    转:为什么数据库选B-tree或B+tree而不是二叉树作为索引结构
    B树、B+树、B*树三者的对比详解
    转载:构造函数不能声明为虚函数,而构造函数可以。为什么?
  • 原文地址:https://www.cnblogs.com/ding-dang/p/13151223.html
Copyright © 2011-2022 走看看