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();
        }
    }
  • 相关阅读:
    PDA智能程序访问WebService,报告“未能建立与网络的连接”
    VS2008中开发智能设备程序的一些总结收藏
    Error: The INF file contains Unicode characters that could not be converted correctly
    在vs2008工程中制作cab包
    linux专题三之如何悄悄破解root密码(以redhat7.2x64为例)
    linux专题一之文件描述符、重定向、管道符、tee命令
    linux的计划
    如何安装RHEL7.2x64 即红帽7.2虚拟机?
    快速排序及查找第K个大的数。
    来来来,做道题,一起防老年痴呆
  • 原文地址:https://www.cnblogs.com/ding-dang/p/13151223.html
Copyright © 2011-2022 走看看