可变实例对象的可见性
Visibility of mutable instance objects
根据“Java concurrency in practice”一书,下面的代码可能会永远执行,或者当 ready 为真时,number 的值可能仍然为 0,建议将变量定义为 volatile。然而,下面列出的程序似乎总是 return 正确的值 (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;
}
}
Is this a phenomenon that occurs very rarely
是的,很少见。然而,鉴于计算机每秒执行数十亿次操作,很少见.
无论何时跨线程访问资源,您必须解决thread-safety。否则,您在部署中的应用程序将遇到零星的错误,这些错误即使不是不可能解决也非常困难。
按照同样的逻辑,测试并发错误是出了名的困难,正如您在问题中看到的那样。
始终尽可能避免线程代码。例如,利用 immutable objects or defensive copies.
必读:Java Concurrency in Practice Brian Goetz 等
作者说服务器 JVM 执行的优化比客户端 JVM 多。
根据“Java concurrency in practice”一书,下面的代码可能会永远执行,或者当 ready 为真时,number 的值可能仍然为 0,建议将变量定义为 volatile。然而,下面列出的程序似乎总是 return 正确的值 (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;
}
}
Is this a phenomenon that occurs very rarely
是的,很少见。然而,鉴于计算机每秒执行数十亿次操作,很少见.
无论何时跨线程访问资源,您必须解决thread-safety。否则,您在部署中的应用程序将遇到零星的错误,这些错误即使不是不可能解决也非常困难。
按照同样的逻辑,测试并发错误是出了名的困难,正如您在问题中看到的那样。
始终尽可能避免线程代码。例如,利用 immutable objects or defensive copies.
必读:Java Concurrency in Practice Brian Goetz 等
作者说服务器 JVM 执行的优化比客户端 JVM 多。