jvm 一个线程对共享数据所做的更改对其他不使用volatile的线程可见

brccelvz  于 2022-11-07  发布在  其他
关注(0)|答案(1)|浏览(128)
import java.util.concurrent.TimeUnit;

public class ThreadTest{
     boolean runStatus = true;
    public void test(){
        System.out.println("test run!!!");
        while (runStatus){
        }
        System.out.println("test end!!!");

    }

    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        new Thread(threadTest::test,"t1").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        threadTest.runStatus = false;
    }
}

在这个JVM中运行代码:
Java版本“1.8.0_65”Java(TM)SE运行时环境(内部版本1.8.0_65-b17)Java HotSpot(TM)客户端虚拟机(内部版本25.65-b 01,混合模式)
runStatus变量中使用的volatile一样,while是stop。但在此JVM中,while是run all:
Java版本“1.8.0_181”Java(TM)SE运行时环境(内部版本1.8.0_181-b13)Java HotSpot(TM)64位服务器虚拟机(内部版本25.181-b13,混合模式)
令人困惑的是,为什么会存在这种现象呢?

jc3wubiy

jc3wubiy1#

较新的JVM执行了允许的优化,并将while循环转换为未检查的无限循环。较旧的JVM是一个“客户端VM”,通常执行较少的优化。客户端VM每次都读取该字段,即使它没有被声明为volatile,这仅仅是因为这样编译代码“更容易”。
当字段没有被声明为volatile或使用lock或synchronized访问时,JVM可以自由地假设没有其他线程会更改字段值,允许将循环重写为while (true) { }
几个月前,Java并发邮件列表上有一个很长的帖子,讨论了您在无限循环方面遇到的相同问题。简单的答案是,因为JVM可以执行内存访问优化,所以总是假设它会。

相关问题