侯哥不怕你
2020-05-25 13:12
采纳率: 50%
浏览 312
已采纳

java中用volatile修饰的静态变量线程可见,不修饰我发现还是可见,不知道怎么回事????

下图:

图片说明

我没有用volatile修饰,在线程中起一个新的线程,在主线程睡眠15秒后,将run改为false,另一个线程就停了,这是不是说明run是线程可见的

图片说明

到底是哪里错了...

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • qybao 2020-05-25 15:22
    已采纳

    因为你的线程里用到log.debug打印了信息,而打印处理的底层代码用到同步锁,所以线程会刷新本地的变量副本
    你把while(run)循环的log.debug注释掉再执行试试看

    已采纳该答案
    1 打赏 评论
  • dabocaiqq 2020-05-25 14:49
    打赏 评论
  • 农夫丶果园 2020-05-25 17:05

    可见性是指, 任意线程对一个变量进行了修改 , 其他变量读到的都是最新的值 .
    CPU为了提高效率会把主内存中的值写到线程独享的工作内存中 , 但跟主内存做同步的时间间隙导致了线程可能无法读到最新的值 , volatile 可以保证每次都去主内存读取 ,所以保证了可见性.
    static 表示这个变量在所有该类的实例中只有一份 , 但还是避免不了从主内存拷贝到工作内存 , 所以无法保证可见性 .
    你运行看看下面这个实验 , 加不加volatile , 结果是不一样的
    // private static volatile int MY_INT = 0;
    private static int MY_INT = 0;

    public static void main(String[] args) {
        new ChangeListener().start();
        new ChangeMaker().start();
    }
    
    static class ChangeListener extends Thread {
        @Override
        public void run() {
            int local_value = MY_INT;
            while (local_value < 5){
                if(local_value != MY_INT){
                    System.out.println("Got Change for MY_INT: " + MY_INT);
                    local_value = MY_INT;
                }
            }
        }
    }
    
    static class ChangeMaker extends Thread{
        @Override
        public void run() {
            int local_value = MY_INT;
            while (MY_INT < 5){
                System.out.println("Increment MY_INT to " + (local_value+1));
                MY_INT = ++local_value;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }
    
    // 不加 volatile
    Incrementing MY_INT to 1
    Incrementing MY_INT to 2
    Incrementing MY_INT to 3
    Incrementing MY_INT to 4
    Incrementing MY_INT to 5
    
    // 加了volatile
    Increment MY_INT to 1
    Got Change for MY_INT: 1
    Increment MY_INT to 2
    Got Change for MY_INT: 2
    Increment MY_INT to 3
    Got Change for MY_INT: 3
    Increment MY_INT to 4
    Got Change for MY_INT: 4
    Increment MY_INT to 5
    Got Change for MY_INT: 5
    
    
    你的这个程序似乎是没有被可见性的问题影响到 , 所以你会有static是不是保证了可见性的疑惑  , 但是单从你的程序来说 , 不足以证明static保证了可见性
    
    打赏 评论

相关推荐 更多相似问题