1

题目描述

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();
}

}

2018-12-11 提问

查看全部 3 个回答

0

volatile所谓的可见性就是直接读取主存, 也就是说忽略CPU缓存

推荐答案

4

已采纳

我把题主的问题在stackoverflow上问了一下,问题连接,有人也给出了比较靠谱的答案:

clipboard.png

然后我又在《Java并发编程实战》一书中找到了与上面结论类似的描述:(3.1.4节)

clipboard.png

不清楚什么原理,我就用结论解释一波,ThreadA在读取ints[0]时,首先要读取ints引用,这个引用是volatile修饰的,在读取这个ints引用时,所有变量都会从主存读取,其中就包含ints[0]

推广链接