我一直在读关于volatile(https://www.ibm.com/developerworks/java/library/j-jtp06197/)的文章,发现有一点说volatile写要比非volatile写贵得多。
我可以理解,考虑到volatile是一种同步方式,volatile写操作的相关成本会增加,但我想知道volatile写操作到底是如何比非volatile写操作昂贵得多;这可能与进行易失性写入时不同线程堆栈之间的可见性有关吗?
最佳答案
这就是为什么,根据你所说的:
易失性写操作比非易失性写操作要昂贵得多,这是因为要保证可见性需要内存围栏,但通常仍比获取锁要便宜。
[…]易失性读取很便宜--几乎和非易失性读取一样便宜
当然,这是正确的:不管底层变量是否易失,内存栅栏操作总是以相同的方式执行写和读操作。
然而,Java中的volatile
不仅仅是易失性和非易失性内存读取。事实上,本质上它与这种区别无关:区别在于并发语义。
想想这个臭名昭著的例子:
volatile boolean runningFlag = true;
void run() {
while (runningFlag) { do work; }
}
如果
runningFlag
不是volatile
,jit编译器实际上可以将代码重写为void run() {
if (runningFlag) while (true) { do work; }
}
不用说,通过在每次迭代中读取
runningFlag
而不读取它所带来的开销比率是巨大的。