题目描述
volatile修饰对象和数组时,只是保证其引用地址的可见性,可为什么我加了volatile之后下面的代码会马上打印“结束”,如果不给数组加volatile就永远不会打印。volatile修饰对象和数组时,线程对其域或元素操作的详细步骤是什么?求大神指点
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
public class b {
public static volatile int[] ints = new int[5];
public static void main(String[] args) throws Exception {
Object o = new Object();
new Thread(() -> {
//线程A
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ints[0] = 2;
}).start();
new Thread(() -> { //线程B
while (true) {
if (ints[0] == 2) {
System.out.println("结束");
break;
}
}
}).start();
}
}
我把题主的问题在
stackoverflow
上问了一下,问题连接,有人也给出了比较靠谱的答案:然后我又在《Java并发编程实战》一书中找到了与上面结论类似的描述:(3.1.4节)
不清楚什么原理,我就用结论解释一波,
ThreadA
在读取ints[0]
时,首先要读取ints
引用,这个引用是volatile
修饰的,在读取这个ints
引用时,所有变量都会从主存读取,其中就包含ints[0]
。