当前位置:网站首页>手写ABA遇到的坑

手写ABA遇到的坑

2022-07-06 14:31:00 Hide on jdk

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 对象,自然两个对象不是同一个。

原网站

版权声明
本文为[Hide on jdk]所创,转载请带上原文链接,感谢
https://blog.csdn.net/u012222011/article/details/125625491