请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

为什么没加volatile,公共变量的更改对子线程还是可见的

import java.util.concurrent.TimeUnit;

public class test1 {
    private static  boolean ready;
    private  static  int num;
    private static  class  NoVisiu implements  Runnable{
        @Override
        public void run() {
            while(!ready){
                System.out.println(num);
            }
            System.out.println(num);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(new NoVisiu());
        t.start();
        TimeUnit.SECONDS.sleep(1);
        num=42;
        ready=true;
        TimeUnit.SECONDS.sleep(1);
    }
}

启动server模式后,按道理说会一直执行 。但是最终会输出42结束。
server模式是怎么启动的?
图片描述

正在回答

2回答

我知道你这个截图的来源,我认为这个截图的说法是有问题的。

即便是server模式,也并不是就不可见,相反,JVM还是会努力保证可见性,进行主内存和工作内存的同步。

0 回复 有任何疑惑可以回复我~
Mydog 2020-01-15 22:43:53

这个好像和我提的System.out.println方法问题类似,System.out.println里面有synchronized代码块修饰,由于ready被设置为true之前,有sleep操作,在sleep执行完后,主线程中ready变为了true,子线程里执行的println方法包含了执行synchronized代码块时,JVM提升了ready变量的可见性,此时while循环终止;


可以把run里面的System.out.println注释掉,或换为num++,这时候就一直无法终止了;


不知道我理解的对不对

0 回复 有任何疑惑可以回复我~
  • Mydog #1
    还可以试下,run方法里面,不用System.out.println(),直接使用
    synchronized (this){   //注意是this锁
    //                    num++;
    }
    遇到synchronized修饰的代码块,也是一样会终止。
    回复 有任何疑惑可以回复我~ 2020-01-15 22:53:28
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信