详解单例模式

来源:互联网 发布:itunes无法连接到网络 编辑:程序博客网 时间:2024/06/08 17:10
     单例模式是一种常用的软件设计模式。     在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。显然单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

下面,详细描述单例模式的几种用法:

用法一

    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;          }      }  

分析:这种写法比第一种弥补了线程安全的问题。但是,执行效率低,99%情况下不需要同步。

用法三

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

分析: 很明显,它没有lazy loading,导致的缺点就是类加载时就初始化,没有按需加载,达到节省资源,加快浏览速度的目的。在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载。

用法四

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

分析: 与第三种一样,知识换了一层外衣,本质是一样的。

用法五

    public class Singleton {          private static class SingletonHolder {          private static final Singleton INSTANCE = new Singleton();          }          private Singleton (){}          public static final Singleton getInstance() {          return SingletonHolder.INSTANCE;          }      }  

分析:这个用法很高级,妙招就在私有内部类SingletonHolder。我们知道,私有内部类可以看做是一个私有属性或者方法,只有在父类Singleton主动调用它时才会执行它的私有属性INSTANCE,这就实现了懒加载,同时,它的线程是安全的。

用法六:枚举

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

分析:这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少看见有人这么写过。

用法七

    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;          }      }  

分析: 这个是第二种方式的升级版,俗称双重检查锁定,详细介绍请查看:http://www.ibm.com/developerworks/cn/java/j-dcl.html

在JDK1.5之后,双重检查锁定才能够正常达到单例效果。