weakCompareAndSetjavadoc 是这样解释的:
如果当前值 == 预期值,则自动将值设置为给定的更新值。
可能会错误地失败并且不提供排序保证,因此很少是 compareAndSet 的合适替代方案。
简而言之,javadoc 是说weak 版本是(或曾经是)提供“较弱”保证的版本。
现在,如您所见,这两种方法的当前实现是相同的。根据 Grepcode 网站上的源代码,从 Java 6 到 Java 8(至少)都是如此。
所以我推测这两种方法的实现是:
最后的解释不太可能。如果两个方法最初实现相同,重新实现它们不同将有破坏预先存在的代码的风险。这是个坏主意,即使对于 Unsafe。
@assylias / @Stefan Gobel 评论了另一种解释。基本上,我们在源代码中看到的“相同代码”实际上可能会被 JIT 编译器重写,从而为两种方法提供不同的机器代码。
这当然是有道理的。 JIT 编译器确实为某些(非本机)方法调用生成了特殊情况代码:所谓的“内在函数”。
在 Java 9 中,weakCompareAndSet 方法被标记为已弃用。源码中的解释是:
此方法具有普通的记忆效应,但方法名称暗示易失性记忆效应(请参阅 {@link #compareAndExchange} 和 {@link #compareAndSet} 等方法)。为避免混淆普通或易失性记忆效应,建议改用 {@link #weakCompareAndSetPlain} 方法。
另一方面,我们现在看到 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 并标记为内在候选。