qq_30680953
qq_30680953
采纳率100%
2016-03-15 05:57 浏览 2.5k
已采纳

多线程间,变量可见性问题。一个线程会永远看不到另一个线程的更新吗?

作者说,由于读线程可能永远发现不了main对ready变量的修改就会永远循环下去,但是貌似不太可能永远读不到main对ready变量修改之后的值吧,可能会由于从栈区复制回堆区时,有几毫秒的误差,read线程读到的是旧值,但堆区值更新之后,read线程就读到了新值了吧,为什么说会永远循环下去呢?图片说明

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

5条回答 默认 最新

  • 已采纳
    qq_30680953 qq_30680953 2016-03-16 00:49

    再回去又读了一遍,有如下解释:
    根据JVM设置,如果设置成server模式会有指令重排,如上述循环判断就会变成if(!ready){while(true){...}}所以就会造成死循环,如果设置成volatile,JVM就不会对这个变量进行指令重排。

    点赞 评论 复制链接分享
  • daidaineteasy 晓呆同学 2016-03-15 06:58

    亲测,线程是能读取到ready值的改变的,可以正常的结束
    并且,看代码没有问题啊,应该不会出现读取不到ready值改变的情况的,一般通过旗标来关闭线程都是这样来操作的。

    点赞 1 评论 复制链接分享
  • qq_30680953 qq_30680953 2016-03-15 07:13

    附上测试代码

    public class NoVisibility {
    private static boolean ready;
    private static int number;
    private static class ReaderThread extends Thread {
    public void run() {
    while (!ready)
    Thread.yield();
    System.out.println(number);
    }
    }
    public static void main(String[] args) {
    new ReaderThread().start();
    number = 42;
    ready = true;
    }
    }
    
    点赞 评论 复制链接分享
  • oyljerry oyljerry 2016-03-15 07:25

    除非线程没有去真正读取更新后的数据,比如一直读的寄存器等。那么就可能读取不到新数据

    点赞 评论 复制链接分享
  • qq_30680953 qq_30680953 2016-03-15 08:07

    这是JAVA并发编程实践 第三章开头的一个例子,是并发编程的经典教材,按道理作者应该不会说错。
    但是为何我在jdk1.7下出来的结果,以及根据我的理解,都不太可能永远死循环。
    求合理解释

    点赞 评论 复制链接分享

相关推荐