首页 > 技术文章 > 设计模式-单例模式之懒汉模式

jason0529 2013-11-26 17:47 原文

     设计模式中对单例模式的定义——“保证一个类仅有一个实例,并提供一个访问它的全局访问点”。很简单一句话,明确信息有两点:1、保证一个实例;2、提供全局访问点。而在多线程中保证唯一的实例就需要对懒汉模式的单例做下修改。

普通懒汉模式:

   1:  class Singleton{
   2:      private Singleton(){}
   3:      private static Singleton singleton ;
   4:      public static Singleton getInstance(){
   5:          if(singleton == null){
   6:              singleton = new Singleton();
   7:          }
   8:          return singleton;
   9:      }
  10:  }

 

这种代码在单线程执行没有问题,但是在多线程中就出现了问题,如果两个线程同时调用getInstance 就new了两个实例。代码修改:

   1:  class Singleton{
   2:      private Singleton(){}
   3:      private static Singleton singleton ;
   4:      public static Singleton getInstance(){
   5:          if(singleton == null){
   6:              synchronized(Singleton.class){
   7:                  if(singleton == null){
   8:                      singleton = new Singleton();
   9:                  }
  10:              }
  11:          }
  12:          return singleton;
  13:      }
  14:  }

      第7行再进行判断一遍的原因:如果两个线程同时调用getInstance,其中线程1执行,线程2阻塞,当线程1执行完毕,singleton已经实例化了;而当线程2进入,如果不做null判断那就继续创建了第二个singleton实例,故需进行双重锁定。

       另外,给方法加同步锁也可以实现效果,但有人说这种方法效率太低,本人没有经过测试,暂且苟同。

   1:  class Singleton{
   2:      private Singleton(){}
   3:      private static Singleton singleton ;
   4:      public synchronized static Singleton getInstance(){
   5:          if(singleton == null){
   6:              singleton = new Singleton();
   7:          }
   8:          return singleton;
   9:      }
  10:  }

这里关于synchronized 方法和 synchronized 块的讨论,http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 这篇帖子写的很好,可以参考。

推荐阅读