JAVA并发编程实战里的一个例子

发布于 2022-09-12 04:20:51 字数 624 浏览 39 评论 0

在看到这本书的第三张的第一个程序例子的时候产生了一些疑问,希望大牛能够帮忙解惑,小弟不胜感激。例子如下:

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;
    }
}

疑惑

作者在后面写到“NoVisiabilty可能会持续循环下去,因为读线程可能永远都看不到ready的值” 为什么呢?在我的理解当中肯定是会停止的呀,有没有可能是书中写错了呢。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心凉怎暖 2022-09-19 04:20:51

我看书里好像是这样, 你这里貌似加了个大括号在while这块(不过不影响), 我大概理解了你的困惑:

现在程序中有2个线程, 一个是main, 一个是 ReaderThread;
由于没有同步, 就存在这样一种可能: ReaderThread先启动执行了, 而且马上进入run(), 这个时候main有可能执行了下面的两个赋值, 也有可能还没有, 好了, 我们假设第二种: 还没有;
此时while(true) 就开始无限循环Thread.yield()--> 这是有可能的, 因为 yield让权了可能马上又开始执行; 而由于没有对ready做任何同步, 在ReaderThread中读取的ready可能一直都没有从主存中同步, 这样就陷入了死循环;
这是小的几率, 但是也是可能的存在;
所以书里会那么说; 不知道我说明白了没有[捂脸]

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;
    }
}
热风软妹 2022-09-19 04:20:51

你要往后面看看,看到Java内存模型就差不多能理解了 书里写的没问题

黎歌 2022-09-19 04:20:51

简单来讲就是主线程修改了readyReaderThread不知道。还以为是false

明媚如初 2022-09-19 04:20:51

线程有自己的工作内存空间, 其他线程改了 ready, 你自己线程空间可能没改.

小嗷兮 2022-09-19 04:20:51

在JDK1.8的环境下试了一下,手动控制线程执行顺序,没有发现无限循环的现象。 推荐你看下这个文章,应该有一些帮助:https://blog.csdn.net/joenqc/article/details/54925700

肥爪爪 2022-09-19 04:20:51

内存可见性问题,去看看JMM

暖伴 2022-09-19 04:20:51

两个方面吧
一个是内存可见性,子线程看到的ready值和主线程的可能不一致。
另一个是每次Thread.yield()之后,还是子线程抢到了执行权。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文