答案 0 :(得分:30)
“原子比较和交换”的x86指令是LOCK CMPXCHG
。该指令创建了一个完整的内存栅栏。
没有创建内存栅栏就没有指令可以完成这项工作,因此compareAndSet
和weakCompareAndSet
很可能会映射到LOCK CMPXCHG
并执行完整的内存栅栏。< / p>
但是对于x86而言,其他架构(包括x86的未来变体)可能会做不同的事情。
答案 1 :(得分:29)
弱比较和交换可以充当完整的volatile变量,具体取决于JVM的实现。事实上,如果在某些架构上不可能以比普通CAS更高效的方式实现弱CAS,我不会感到惊讶。在这些体系结构中,很可能是弱CAS实现与完整CAS完全相同。或者可能只是因为你的JVM没有太多的优化使得弱CAS变得特别快,所以当前的实现只调用一个完整的CAS,因为它可以快速实现,未来的版本将改进这个
JLS简单地说弱CAS没有建立发生之前的关系,所以只是没有保证它导致的修改在其他线程。在这种情况下你得到的只是保证比较和设置操作是原子的,但不能保证(可能)新值的可见性。这与保证不会被看见不一样,所以你的测试与此一致。
一般情况下,尽量避免通过实验对与并发相关的行为做出任何结论。有许多变量需要考虑,如果你不遵循JLS保证的正确性,那么你的程序可以随时中断(可能在不同的架构上,也许在更多的架构下)由代码布局稍有变化引起的积极优化,可能是在JVM的未来版本中尚未存在,等等。 永远有理由认为你可以逃脱一些声称无法保证的东西,因为实验表明它“有效”。
答案 2 :(得分:6)
weakCompareAndSwap
保证更快;它只是允许更快。您可以查看OpenJDK的开源代码,了解一些聪明人决定使用此权限做什么:
即:它们都被实现为单行
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
它们具有完全相同的性能,因为它们具有完全相同的实现!(至少在OpenJDK中)。其他人已经注意到这样一个事实,你无论如何都无法在x86上做得更好,因为硬件已经为你提供了“免费”的一系列保证。只有像ARM这样的简单架构才能让你担心它。