AtomicStampedReference#compareAndSet 使用逻辑连接词顺序执行检查

问题描述 投票:0回答:1
public boolean compareAndSet(V   expectedReference,
                             V   newReference,
                             int expectedStamp,
                             int newStamp) {
    Pair<V> current = pair;
    return
        expectedReference == current.reference &&
        expectedStamp == current.stamp &&
        ((newReference == current.reference &&
          newStamp == current.stamp) ||
         casPair(current, Pair.of(newReference, newStamp)));
}

这是compactAndSet

AtomicStampedReference
方法的源代码。

为什么使用

newReference == current.reference && newStamp == current.stamp
?这里的多个布尔逻辑判断是原子的吗?如果不是,判断完
expectedReference == current.reference && expectedStamp == current.stamp
后,如果其他线程将
current.reference
修改为
newReference
,将
current.stamp
修改为
newStamp
,则会返回
true
,不执行
casPair(current, Pair.of(newReference, newStamp)
。但实际上,这个修改是由其他线程完成的,为什么返回true?

java multithreading
1个回答
0
投票

这里重要的部分是第一个声明:

Pair<V> current = pair;

当您查看

casPair
方法时,您可以看到它交换了整个对,并且Pair
字段是
final

因此,它不会逐个比较值,而是首先获取两个值,然后比较已经获得的值。因此

newReference == current.reference && newStamp == current.stamp
实际上并不直接检查接收器的状态,这在检索
Pair
时已经完成了。

但实际上这个修改是由其他线程完成的,为什么会返回true呢?

这本质上是同一件事。使用

Pair<V> current = pair;
以原子方式检索该值,然后与其进行比较。仅当
expectedReference
current.reference
newReference
(以及
expectedStamp
current.stamp
newStamp
)相对于
Pair<V> current = pair;
检索的对象相同时,才会发生这种情况。

在这种情况下,如果该值已经具有该确切值,则您将将该值设置为新值。在这种情况下,您无需更改值即可获得相同的行为,因为将值设置为自身不会产生任何副作用。如果其他人同时更改了

AtomicStampedReference
,则可以认为该更改是“稍后”发生的。

© www.soinside.com 2019 - 2024. All rights reserved.