嗯,看了些链接
https://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#reordering
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://blog.zhaojie.me/2009/09/double-check-failure-answer.html
还是没想明白就算第一个线程中创建对象与给引用赋值的顺序反了,难道syschronized关键字不能保证这两个操作都执行完之后在刷到主内存吗?
在第一个线程执行过程中,第二个线程读取主内存中的引用,因该还是为null的阿
再贴一个InfoQ上的关于volatile的文,http://www.infoq.com/cn/articles/java-memory-model-4?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk
这个系列虽然写的不错,但是感觉还是有点问题。根据http://www.infoq.com/cn/articles/java-memory-model-5?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk这篇文章的说法,synchronized应该可以保证内部的代码全都执行完毕
之后再去更新主内存。
唉,有人指点下就好了
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
恩,这是我半年多前的问题,现在已经搞明白了。这个问题其实说得是线程A正在执行instance = new Instance()的操作,而线程B开始执行if(instance==null)的判断,当不存在volatile保证线程可见性以及 保证构造函数在整个对象构造完成前执行完毕 的时候,线程B可能会看到一个不完整的instance对象,因为java的某些实现会在内存中开辟一片存储对象的区域后直接返回内存的引用,所以线程B判断不为null。从而得到不完整的对象。