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>A、B线程同时进入了第一个if判断
b>A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();
c>由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。
d>B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
e>此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了
此时的问题是:有可能instance不是null但是没有被初始化的情况。。