Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

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

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

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的值” 为什么呢?在我的理解当中肯定是会停止的呀,有没有可能是书中写错了呢。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

我看书里好像是这样, 你这里貌似加了个大括号在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;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...