什么?Volatile会造成死循环?假的

今天在系统的学习Volatile,看到一个例子,运行起来会死循环,而加了一个Volatile就不会,然后引出结论 ----- Volatile可以使线程回写主存。很多教学视频用这个例子来教学。
我一看,不对劲。因为像例子里面的代码造成的死循环,在我几年的开发过程中,是没有遇到过的。其次,据我所知,在没有加Volatile的情况下,线程的内存不存在不回写的情况。之所以会线程不安全是因为线程的内存没有实时与主存同步,而加了Volatile可以保证线程可见性。

来看死循环具体的实现代码:


public class Main {

   private  boolean flag = false;

   public static void main(String[] args) throws UnsupportedEncodingException {

      Main main = new Main();

      new Thread(new Runnable() {
         @Override
         public void run() {
            System.out.println(11111);
            while(!main.flag) {
            }
            System.out.println(22222);
         }
      }).start();

      try {
         Thread.sleep(100);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }

      new Thread(new Runnable() {
         @Override
         public void run() {
            System.out.println(33333);
            try {
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
            main.flag = true;
            System.out.println(44444);
         }
      }).start();
   }
}

如上述代码,会导致线程一死循环。然后加上Volatile就不会了。
但是,我看着就觉得不对劲,然后我试着在主线程去访问main.flag,发现也不会死循环了。再者,在while循环里,加上一行打印,也不会死循环了。

后面我查阅了一些资料,发现只要把jit优化去掉,就不会死循环了。
可以把上述代码,进行javac编译,然后 执行 java -Xint Main。(-Xint 的意思就是把jit优化去掉)

后面我再查阅了一些资料,发现 while(main.flag) 这一行代码,在Jit的优化下,会变成

boolean temp = main.flag;
while(temp){}

看来,这和可见性是一点关系都没有,而教学的人用这个人例子来证明可见性简直就是牛头不对马嘴。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值