根据《java并发在实践中》一书,当ready为true时,下面的代码可能永远执行,或者number的值可能仍然是0,建议将变量定义为volatile。但是,下面列出的程序似乎总是返回正确的值(42),而不是过时的值,即使我尝试了多次。这是一种很少发生的现象吗?
public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread{
public void run(){
System.out.println("Thread started =" + ready + " " + number);
while(!ready){
Thread.yield();
}
System.out.println("value is" + number);
}
}
public static void main(String[] args) throws InterruptedException {
new ReaderThread().start();
Thread.sleep(10000);
number = 42;
ready = true;
}
}
2条答案
按热度按时间2ekbmq321#
作者说服务器jvm比客户端jvm执行更多的优化。
nr9pn0ug2#
这是一种很少发生的现象吗
是的,很少。然而,考虑到每秒处理数十亿次事情的计算机,罕见的情况相当普遍。
无论何时跨线程访问资源,都必须解决线程安全问题。否则,部署中的应用程序将遇到偶发的错误,即使不是不可能解决,也非常困难。
按照同样的逻辑,测试并发错误是出了名的困难,正如您在问题中看到的那样。
尽可能避免使用线程代码。例如,使用不可变对象或防御副本。
必读:brian goetz等人的java并发实践。