Welcome everyone

单例模式之double check

设计模式 汪明鑫 504浏览 1评论

这个在面试美团时让手写了,并说出如何理解,差点忘了

 

public static Singleton getInstance()
{
  if (instance == null)                  //1
  {
    synchronized(Singleton.class) {      //2
      if (instance == null)              //3
      {
         instance = new Singleton();     //4
      }
    }
  }
  return instance;
}
第一个if 保证对象为空才会有资格竞争锁 ,保证了代码的效率

第二个if 保证如果其他线程已经创建出了,就不会再new ,直接返回之前已经创建好的对象,保证了单例

上面的代码存在一定的问题,问题的原由在第4句代码  instance =new Singleton()
这句代码可以分解为三句伪代码:
memory = allocate();       //1:分配对象的内存空间
ctorInstance(memory);    //2:初始化对象
instance = memory;        //3:设置instance指向刚分配的内存地址

上述的第2句代码和第3句代码可能会重排序

如果重排序,有线程将可能会拿到未被初始化的对象

 

解决办法:用volatile修饰instance

 

private volatile static Singleton instance;

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

volatile在多线程下禁止三句伪代码的重排序

转载请注明:汪明鑫的个人博客 » 单例模式之double check

喜欢 (0)

说点什么

1 评论 在 "单例模式之double check"

提醒
avatar
排序:   最新 | 最旧 | 得票最多
trackback

[…] 单例模式之double check […]

wpDiscuz