讨论/技术交流/题目求助|字节跳动一面问题|读取volatile变量会影响其他no-volatile变量在工作内存的值吗?/
题目求助|字节跳动一面问题|读取volatile变量会影响其他no-volatile变量在工作内存的值吗?

面试官分享的代码,为什么下面的代码中线程1会正常停止,完全想不明白,代码如下:

public class Vol {

    boolean run = true;
    volatile int s = 1;
    public static void main(String[] args) throws InterruptedException {

        Vol v = new Vol();
        //thread 1
        new Thread(() ->{
            while (v.run) {
               
                int a = v.s;    //如果不注释这行,线程1无法中止
            }
        }).start();
        //thread 2
        new Thread(() ->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            v.run = false;
            System.out.println("set run false");
        }).start();
    }
}

代码如上,while(run){} 判断线程是否继续循环,run是一个非volatile变量,因此一般情况线程1无法读取到线程2对run的修改,所以无法停止;但是如果在while中加入int a = v.s, v.s是一个volatile变量,线程1就可以停止了。代码里只对v.s进行读取难道也会读取主内存里run的值吗?

更新:
感谢各位的解答和提供信息,目前比较合理的回答:

https://www.zhihu.com/question/348513270

https://stackoverflow.com/questions/67233073/does-reading-a-volatile-variable-affects-the-value-of-other-no-volatile-variable

8

在Stackoverflow上问到的一个答案,求大佬解释分析一下:
image.png
image.png
image.png
按他这个说法,这段代码整个就是不确定的了,即使我没有加上int a = v.s, 线程1还是可能会停下来,因为没有happend-before?

1
展开全部 34 讨论