private static AtomicReference<Integer> atomicReference = new AtomicReference<>(0);
private static AtomicReference<Integer> atomicReference1 = new AtomicReference<>(100);
atomicReference.compareAndSet(0, 2);
atomicReference.compareAndSet(0, 3);
atomicReference.compareAndSet(2, 4);
atomicReference.compareAndSet(3, 5);
System.out.println(atomicReference.get());
atomicReference1.compareAndSet(100, 200);
atomicReference1.compareAndSet(100, 300);
atomicReference1.compareAndSet(200, 400);
atomicReference1.compareAndSet(300, 500);
System.out.println(atomicReference1.get());
然而运行出来的结果
atomicReference为4
atomicReference1为200.
问题.atomicReference1为什么是200 而不是400
首先compareAndSet使用==比较,看注释:
Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
其次为什么128以内的整数可以而超过128不可以?
对于int字面量java会进行装箱将其转换成Integer对象,调用的是Integer.valueOf方法,
看源码你就明白了,128以内的会使用缓存,同一个int字面量返回同一个对象用==比较为true,而超过128返回不是同一个对象,==为false,equal才是true:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
祝你好运!
这个问题眼前一亮,好问题。我们一般会使用AtomicReference的CAS保证原子性,但是它是通过比较引用是否相同判断是否可以更新。
atomicReference1.compareAndSet(100, 200);
atomicReference1.compareAndSet(100, 300);
atomicReference1.compareAndSet(200, 400);
atomicReference1.compareAndSet(300, 500);
System.out.println(atomicReference1.get());
初始值为常量池中的100,第一步中100会先转成Integer.valueOf(100),这个对象其实就是常量池中的100,第一步相同可以更新为200。
再向后面Integer.valueOf(200) != Integer.valueOf(200),所以以后都不等,最终结果为200.