我在“Java Concurrency in Practice”一书中遇到了以下示例。
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;
}
}
其进一步表述为:
NoVisibility could loop forever because the value of ready might never become visible to the reader thread. Even more strangely, NoVisibility could print zero because the write to ready might be made visible to the reader thread before the write to number, a phenomenon known as reordering.
我可以理解重新排序问题,但我无法理解可见性问题。为什么ready的值可能永远不会对读取器线程可见?一旦主线程将值写入ready
,读取器线程迟早会有机会运行并且可以读取ready
的值。为什么主线程在 ready
中所做的更改可能对读取器线程不可见?
最佳答案
ReaderThread
的 run()
方法可能永远不会看到 ready
的最新值,因为它可以自由地假设和优化该值不在其线程之外进行更改。可以通过使用该语言的相关并发特性来消除这种假设,例如在 ready
的声明中添加关键字 volatile
。
关于java - java并发编程中的可见性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31633699/