解决方案 »

  1.   

    ready = false;就能进了...
      

  2.   

    从概率上来讲,main()方法有可能刚刚执行完t.start()以后,ReaderThread 线程开始执行,这时main()方法的number = 42;ready = true;还未执行,然后就会出现你说的打印0的情况。但这种情况在现代的计算机上几乎是不可能发生的,因为现在的处理器基本都是多核多线程,主线程里起一个子线程后,主线程会继续往下执行(因为多核多线程,不存在把CPU让给子线程),而起一个子线程又是需要消耗一点时间的(分配资源、内存什么的),所以就算你在t.start()和        number = 42;这行代码中间加一行        Thread.yield();也基本不会出现那种子线程先执行的情况。想模拟这种情况可以在那两行代码中间加一个耗时足够的运算,其实和一个简单的sleep没啥区别
    public class NoVisibility {
        private static boolean ready = false;
        private static int number;
        volatile static double foo = Math.PI; 
         
        private static class ReaderThread extends Thread {
            public void run() {
                System.out.println("ready->" + ready);
                while(!ready) {
                    Thread.yield();
                    System.out.println(number);
                }
            }
        }
         
        public static void main(String[] args) {
            Thread t = new ReaderThread();
            t.start();
            
            for (int i=0; i<10000; i++) {
                foo += 1.0/foo;
            }
            
            number = 42;
            ready = true;
        }
    }
      

  3.   

    Thread t = new ReaderThread();
    这句加个断点,就能看到为0 的情况