首页 > 代码库 > 设计模式之单例模式

设计模式之单例模式

  单例模式在软件开发当中用的是比较多的,在Spring的配置文件中,如果没有特殊声明,实例将以单例模式初始化。同时单例模式也比较简单,在网上看过一篇《单例模式的七种写法》,七种我想不一定都需要,下面我就介绍我认为比较常用的几种。

  一、饿汉式:

    public class Singleton {          private static Singleton instance = new Singleton();          private Singleton (){}          public static Singleton getInstance() {          return instance;          }      }  

  饿汉式的精华就在于对象在实例化时就初始化单例对象,就像饿虎扑食般地急不可耐,这样的缺点就是增加了启动的开销以及可能的资源浪费,不过应该无所谓了。

  二、懒汉式:

  懒汉式涉及到线程的安全性的问题,先来看一个线程不安全的。

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

  懒汉式的精华在于需要使用对象的时候才进行初始化,上面的代码如果有多个线程同时调用时,可能会出现多个实例,这个也就违背了单例模式的初衷。下面是线程安全的代码。

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

  这种写法将getInstance()作为一个同步块,来确保实例的单一性,遗憾的是效率有点低。后来又进行了改进,叫做双重校验锁,它不像上面的代码是对整个getInstance()方法进行同步,而是对立面的实例创建的两行进行同步,从而很好地解决了安全和性能的问题。

    public class Singleton {          private volatile static Singleton singleton;          private Singleton (){}          public static Singleton getSingleton() {          if (singleton == null) {              synchronized (Singleton.class) {              if (singleton == null) {                  singleton = new Singleton();              }              }          }          return singleton;          }      }  

  三、枚举法:

  上面的方法已经足以应付正常的情况,但是在反射或者反序列化时,仍有可能生成多个实例,根据effective java中的说明,枚举方法可以完美地解决上述所有问题。

    public enum Singleton {          INSTANCE;          public void whateverMethod() {          }      }  

  PS:在单例模式中构造器用private修饰,防止显示调用构造函数,生成实例。

  

设计模式之单例模式