weakCompareAndSet
javadoc是这样解释的:
如果当前值 == 预期值,则自动将值设置为给定的更新值。
可能会错误地失败并且不提供排序保证,因此很少是 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);
}
whereVALUE
被声明为 a java.lang.invoke.VarHandle
。上面使用的VarHandle
方法被native
标记为内在候选方法。