分布式内参4:volatile与一致性
备注:本内参系列,是学习
TinyMQ
项目之前的必读内容!
在Java中,synchronized修饰的是代码块,代码块里面的变量都实现了内存可见性。内存可见性的底层是CPU的指令实现的。volatile修饰的是变量,它的作用也是实现内存可见性,底层用的同一个CPU指令。可以这样理解:synchronized里面的变量都是volatile修饰的。
我们都用过synchronized,但是用volatile机会很少,其实换个角度想想,synchronized里面的变量完全可以看做被volatile修饰,这样一想,是不是感觉volatile离我们很近很亲切,不陌生了。
这个提问来源于群里的成员:volatile除了保证内存可见性,还有个作用是防止指令重排。
关于这一点,我想做一个说明和补充。
这个成员提出:JVM会对new对象的过程进行指令重排,先分配空间,再把空间地址返回给变量,最后才进行对象实例化,加了volatile后会强制先进行实例化,最后才把对象地址返回被变量。
我觉得,指令重排是不是最终的思想来源还是内存可见性呢?如果两个互不相关的思想,用到一个事物上,感觉怪怪的。
我后来想了想,寄存器和主存的隔离造成了数据的不一致,volatile的初衷是保证数据的强一致性,当赋值基本简单类型的时候,这种一致性很容易实现。但是赋值对象类型的时候,这种一致性分为强一致性和弱一致性,重排是弱一致性,而有序则是强一致性,volatile的目的是强一致性,所以最终它要求指令不得重排。现在我感觉可以把可见性和有序性都统一到一致性上面了。