可能在“number = 42;”还没执行就打印了,所以打印0
无限循环的应该是理论可以忽略

解决方案 »

  1.   

    内存可见性,number和ready和能被优化器保存在寄存器中二不在内存中,这样你做的修改时看不到的!
      

  2.   

    不明白
    去看《Java并发编程实践》这本书吧!
    这个例子就是那里的!
    讲的很清楚!
      

  3.   

    死循环倒有可能,打印0这种情况是怎么回事?在ready等于true之前number已经等于42了。
      

  4.   

    楼主看得就是并发编程实战吧,个人觉得和机子有关系,一般数据操作都是在内存中的,这样线程是能够发现的,但是可能存在一种情况,这些操作的数据的值不在内存中而是被意外放到寄存器当中,而寄存器是供CPU使用的,程序代码根本访问不到,这样就造成了一种特殊的不可见性,自然可能出现,ready和number被线程访问时一致都是默认值,而不是主线程赋值后的42和true,因为程序根本找不到这两个值.我是这样理解的,别喷啊
      

  5.   

    首先类加载会初始化ready和number的值分别为false和0,可能会出现的情况应该有4种,楼主执行的结果是一种,
    剩下的3种情况应该是这样的:
    1.无限循环,number的值为0:在主线程即main方法中对ready的设置(即ready = true)还没来得及写回主存(静态变量保存在方法区),ReaderThread 线程就已经读取了ready的值(并保留了副本),然后加载到Java栈中,此时ready 一直为false所以出现死循环。number的值也可以类似推理,在主线程即main方法中对number的设置(即number= 42)还没来得及写回主存(静态变量保存在方法区),ReaderThread 线程就已经读取了number的值(并保留了副本),然后加载到Java栈中,此时number一直为0(只是没有打印出来而已);2.无限循环,number的值为42:在主线程即main方法中对ready的设置(即ready = true)还没来得及写回主存(静态变量保存在方法区),ReaderThread 线程就已经读取了ready的值(并保留了副本),然后加载到Java栈中,此时ready 一直为false所以出现死循环。在主线程即main方法中对number的设置(即number= 42)后(即number的值已经写回了主存),ReaderThread 线程才开始执行此时读取的number为42(只是没有打印出来而已);3.输出0:在主线程即main方法中对ready的设置(即ready = true)后(即ready的值已经写回了主存),还没来得及写回主存(静态变量保存在方法区),ReaderThread 线程就已经读取了number的值(并保留了副本),然后加载到Java栈中,此时number为0;至于为什么会出现ready = true写回主存后,number = 42还没写回主存。这应该是由于Java虚拟机的一种优化技术叫指令重排序,number = 42不一定会在ready = true前面执行,得看Java虚拟机是怎么优化的。
      

  6.   

    想错了,应该不会有死循环,ready=true终止循环。
      

  7.   

    试了oracle 和 ibm 的jvm
    client 和 server模式下都输出42