我在“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 可能永远循环,因为ready 的值可能永远不会对阅读器线程可见。更奇怪的是,NoVisibility 可以打印零,因为在写入 number 之前,ready 的写入可能对 reader 线程可见,这种现象称为重新排序。
我可以理解重新排序问题,但我无法理解可见性问题。为什么ready
可能永远不会对读者线程可见?一旦主线程将值写入ready
,阅读器线程迟早会有机会运行并且可以读取 的值ready
。为什么主线程所做的更改ready
可能对阅读器线程不可见?