class Data {
private int value;
}
volatile Data data = new Data();
Thread1 更改了 data.value ,data.value的新值 对其他Tread 可不可见?
网上很多说 volatile 仅针对被其修饰的变量可见,不保证里面的值。
http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html
https://www.logicbig.com/tutorials/core-java-tutorial/java-multi-threading/volatile-ref-object.html
另外有说法是其关联的都可见
https://segmentfault.com/q/1010000017341320
从实际使用上好像是都可见。
真相到底是什么呢?
不保证
只保证可见性(MESI协议),有序性(防指令重排,一些read,load等指令),不能保证原子性
好问题,make一下
先用一段官方示例来来看下相关的内存模型:
假设 p == q, p.x == 0
首先原本的逻辑如下:
我们可以看出,最后r2 r4 r5的值取决于线程2中r6.x=3的时机,如果发生在r3=q之前,r2=r1.x之后,则
r2 = 0,r4 =3 ,r5 = 3.
但是上述的代码可能被编译器进行优化成如下代码 r5 = r2,因为都是取值本地的r1.x
如果r1对应的p具有volatile关键字,我的猜想是就不会出现 r5=r2,对于r5=r1.x读的肯定是最新值
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.1.4
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4
最难受的是,最后官方并没有结合例子讲解最后的重排序和volatile,所以最后的结论只能是猜想