单实例懒汉模式幷包保证成功

a) public static Singleton getInstance() {  

b)         if (instance == null) {  

c)             synchronized (instance) {  

d)                 if (instance == null) {  

e)                     instance = new Singleton();  

f)                 }  

g)             }  

h)         }  

i)         return instance;  

j)     }  

Java指令中创建对象和赋值操作是分开进行的,也就是说 instance=new Singleton()是分两步进行的。但是jvm并不保证这两个操作的先后顺序,也就是说有可能会jvm会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。

这样上面的代码就可能会出现下面的错:

a>AB线程同时进入了第一个if判断

b>A首先进入synchronized块,由于instancenull,所以它执行instance = new Singleton();

c>由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。

d>B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。

e>此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了

此时的问题是:有可能instance不是null但是没有被初始化的情况。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章