Eri*_*ric 12 java atomicreference
源代码是一回事.
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);
}
Run Code Online (Sandbox Code Playgroud)
重点是什么?
x86具有用于实现CAS的LOCK CMPXCHG指令,该指令是原子的,并提供(近)最大的顺序保证,您无法真正削弱它。
但是在其他平台(例如PowerPC或ARM)上,CAS是由若干条指令序列实现的,这些指令将LL / SC和内存屏障作为单独的构建块提供。这为您的CAS在订购和故障保证方面的强大程度提供了一定的回旋余地。相反,这意味着全功能CAS比某些并发算法所需的指令序列成本更高。
因此,weakcas可让您在此类平台上进行一些权衡。
Javadoc对于弱化排序的确切含义是含糊的,因为当前无法用Java内存模型来表示它。在将来与C ++ 11内存模型更紧密地结合在一起时,可能会对此进行修订。
JSR-133 Cookbook的Multiprocessor一章中的表格概述了平台之间的差异。
该weakCompareAndSet javadoc的解释是这样的:
如果当前值==期望值,则以原子方式将该值设置为给定的更新值。
可能会虚假地失败,并且不提供排序保证,因此很少是compareAndSet的适当替代方法。
简而言之,javadoc说该weak版本是(或曾经是)提供“较弱”保证的版本。
现在,正如您所观察到的,这两种方法的当前实现是相同的。根据Grepcode网站上的源代码,从Java 6到Java 8(至少)都是如此。
因此,我推测这两种方法的实现方式之一是:
最初是不同的,但由于对以下实施的全面检查而变得相同Unsafe:
最初是相同的,并且指定了差异(但未实现),因为设计人员认为可能存在性能优势。
最后的解释是不可能的。如果最初以相同的方式实现两种方法,则将它们重新实现为不同的方法可能会破坏先前存在的代码。即使对于,这也是一个坏主意Unsafe。
@assylias / @ Stefan Gobel评论了另一种解释。基本上,我们在源代码中看到的“相同代码”实际上可以由JIT编译器重写,以为这两种方法提供不同的机器代码。
这当然是合理的。对于某些(非本机)方法调用,JIT编译器确实具有特殊情况的代码生成:所谓的“内部”。