You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AtomicStampedReference.compareAndSet逻辑判断与原子性疑问

AtomicStampedReference.compareAndSet 源码分析与问题解答

源码展示

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)));
}

问题

  1. 为何该方法要加入newReference == current.reference && newStamp == current.stamp判断?
  2. 这些多布尔逻辑判断是否具备原子性?
  3. 若不具备,当判断完expectedReference == current.reference && expectedStamp == current.stamp后,若其他线程将current.reference修改为newReference且current.stamp修改为newStamp,此时方法会返回true且不执行casPair,但该修改实际由其他线程完成,为何要返回true?

解答

1. 加入该判断的原因

核心是避免无意义的CAS操作。如果当前的引用和戳记已经和要设置的新值完全一致,调用casPair做原子更新纯粹是浪费性能——底层CAS指令是相对重的操作,能省则省。直接返回true就够了,因为目标状态已经达成,没必要多此一举。

2. 布尔逻辑判断的原子性

这些判断不具备原子性。虽然current = pair这一步是原子的(因为pair被volatile修饰,保证可见性和单次读取的原子性),但后面的多个==比较是分步执行的普通内存操作,没有加锁也没有原子指令保护。从拿到current到完成所有布尔判断的间隙,其他线程完全有可能修改pair的值。

3. 该场景返回true的合理性

compareAndSet的核心语义是:只要对象最终处于我期望的新状态,就返回true;否则返回false,而不是“必须由我自己完成修改才返回true”。

举个实际场景:我本来想把状态从A改成B,刚确认当前是A,另一个线程抢先把它改成了B。对我来说,目标已经达成了,不需要再做任何操作,返回true完全符合预期——毕竟我调用这个方法的目的是让对象处于新状态,至于谁完成的修改,并不影响最终结果的有效性。

内容的提问来源于stack exchange,提问作者xllz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:04:59