• 手写ABA遇到的坑


    AtomicStampedReference<Integer> stampedReference = new AtomicStampedReference<>(100, 1);

    Thread t1 = new Thread(()->{
        boolean b = stampedReference.compareAndSet(100, 200, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t1           "+b);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        boolean b1 = stampedReference.compareAndSet(200, 100, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t1           "+b1+"  "+ stampedReference.getReference()+" "+stampedReference.getStamp());
    },"t1");
    t1.start();
    
    Thread t2 = new Thread(()->{
        System.out.println(stampedReference.getReference()+"   "+stampedReference.getStamp());
        boolean b = stampedReference.compareAndSet(200, 300, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t2           "+b);
        boolean c = stampedReference.compareAndSet(300, 200, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t2           "+c);
    },"t2");
    t2.start();

    运行结果:

     居然发现A线程换回去失败了:最后终于想明白了,Integer超过128会new,而不是从缓存中拿,所以会比较失败。

    修改成小于128的值,观察结果:

    Thread t1 = new Thread(()->{
        boolean b = stampedReference.compareAndSet(100, 105, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t1           "+b);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        boolean b1 = stampedReference.compareAndSet(105, 100, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t1           "+b1+"  "+ stampedReference.getReference()+" "+stampedReference.getStamp());
    },"t1");
    t1.start();
    
    Thread t2 = new Thread(()->{
        System.out.println(stampedReference.getReference()+"   "+stampedReference.getStamp());
        boolean b = stampedReference.compareAndSet(105, 104, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t2           "+b);
        boolean c = stampedReference.compareAndSet(104, 105, stampedReference.getStamp(), stampedReference.getStamp()+1);
        System.out.println("t2           "+c);
    },"t2");
    t2.start();

     发现aba结果成功和预期的一样。大家使用Integer的时候一定要注意范围不能超过128,否则会new 对象,自然两个对象不是同一个。

  • 相关阅读:
    FPGA:单比特跨时钟域、多比特跨时钟域(更新中)
    深度学习之Python,OpenCV中的卷积
    安装Hadoop,启动hadoop(每次都用),设置免密码登陆
    【开源讲解】
    2分钟快速安装 `nginx` 和配置 `keepalived`
    nodejs-express项目初始化
    认识 Redis client-output-buffer-limit 参数与源码分析
    优化双重循环
    语义分割之RTFormer介绍
    Markdown还能这么玩?这款开源神器绝了!
  • 原文地址:https://blog.csdn.net/u012222011/article/details/125625491