源代码是同一回事。

public final boolean compareAndSet(V expect, V update) {
    return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

public final boolean weakCompareAndSet(V expect, V update) {
    return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

重点是什么?

最佳答案

weakCompareAndSet javadoc对此进行了解释:

简而言之,javadoc说weak版本是(或曾经是)提供“较弱”保证的版本。
现在,您将看到,这两种方法的当前实现是相同的。根据Grepcode网站上的源代码,从Java 6到Java 8(至少)都是如此。
因此,我推测这两种方法的实现方式之一是:

  • 本来是不同的,但是由于对Unsafe的实现进行了全面的改进,所以变得相同:
  • 为方便起见(例如,节省实现工作量
  • ,因为“弱”版本或
  • 的假定性能
  • ,因为“弱”版本有问题;例如很难正确使用。

  • 最初是相同的,并且指定了差异(但未实现),因为设计人员认为可能存在性能优势。

  • 最后的解释是不可能的。如果最初以相同的方式实现两个方法,则将它们重新实现为不同的方法可能会破坏现有的代码。即使是Unsafe,这也是一个坏主意。

    @assylias/@ Stefan Gobel评论了另一种解释。基本上,我们在源代码中看到的“相同代码”实际上可以由JIT编译器重写,以为这两种方法提供不同的机器代码。
    这当然是合理的。 JIT编译器确实为某些(非 native )方法调用生成了特殊情况的代码:所谓的“内部”。

    在Java 9中,weakCompareAndSet方法标记为不推荐使用。源代码中的解释是:

    另一方面,我们现在看到compareAndSet的实现与weakCompareAndSet/weakCompareAndSetPlain的实现不同:
    public final boolean compareAndSet(V expectedValue, V newValue) {
        return VALUE.compareAndSet(this, expectedValue, newValue);
    }
    
    public final boolean weakCompareAndSet(V expectedValue, V newValue) {
        return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue);
    }
    
    其中VALUE声明为java.lang.invoke.VarHandle。上面使用的VarHandle方法是native,并标记为固有候选者。

    07-24 13:34