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