双重检查 单例模式 会出现空指针问题

Posted epmouse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双重检查 单例模式 会出现空指针问题相关的知识,希望对你有一定的参考价值。

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {  //1
      if (instance == null)          //2
        instance = new Singleton();  //3
    }
  }
  return instance;
}

 

简单的理解:

由于java实例化一个对象的操作(new)不是原子性的。所以在线程a 在执行到 代码  3 处时,当3完成了一部分时,instance就已经非null了,

    但是此时实例对象并没有构造完成。假如这个时候线程b进来if语句就会得道instance不是null, 会直接拿到未完成的 instance,从而导致空指针。

说明:

java创建一个对象,在java虚拟机上会进行以下三步操作

1、给instance分配内存

2、调用构造方法 初始化

3、指向内存分配区域

这里牵涉到一个重排序的问题。也就是123的执行顺序是随机的。而其中的3执行完后对象就不为null了

所以当3在2的前面执行时,当2执行完3还未执行时,其他线程进来就会返回未执行3的实例对象,从而导致空指针

 

以上是关于双重检查 单例模式 会出现空指针问题的主要内容,如果未能解决你的问题,请参考以下文章

Java单例模式中双重检查锁的问题

单例模式双重检查(DCL)引发的多线程问题

双重检查锁实现单例模式的线程安全问题

单例模式双重检查锁模式为什么必须加 volatile?

单例模式双重检查锁模式为什么必须加 volatile?

如何实现一个单例模式 c#双重锁检查