java—可变示例对象的可见性

ryevplcw  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(349)

根据《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;
    }
}
2ekbmq32

2ekbmq321#

作者说服务器jvm比客户端jvm执行更多的优化。

nr9pn0ug

nr9pn0ug2#

这是一种很少发生的现象吗
是的,很少。然而,考虑到每秒处理数十亿次事情的计算机,罕见的情况相当普遍。
无论何时跨线程访问资源,都必须解决线程安全问题。否则,部署中的应用程序将遇到偶发的错误,即使不是不可能解决,也非常困难。
按照同样的逻辑,测试并发错误是出了名的困难,正如您在问题中看到的那样。
尽可能避免使用线程代码。例如,使用不可变对象或防御副本。
必读:brian goetz等人的java并发实践。

相关问题