概述
大家都知道,在windows系统里只能打开一个“任务管理器”。同理,在程序开发中,需要某些类只能创建一个对象,因为随意创建这些类的对象没有任何意义,甚至造成系统性能下降(因为频繁地创建对象、回收对象带来的系统开销问题)。这时用到了一种常用的软件设计模式“单例模式”,通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。通常单例模式在Java语言中,有两种构建方式:
- 懒汉方式。指全局的单例实例在第一次被使用时构建。
- 饿汉方式。指全局的单例实例在类装载时构建。
第一种(懒汉,线程不安全):
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。
第二种(懒汉,线程安全):
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这种写法能够在多线程中很好的工作,而且看起来它也具备很好的lazy loading,但是效率低。
第三种(饿汉):
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
这种方式基于class loder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,这时候初始化instance显然没有达到lazy loading的效果。
第四种(饿汉,变种):
public class Singleton { private Singleton instance = null; static { instance = new Singleton(); } private Singleton (){} public static Singleton getInstance() { return this.instance; } }
表面上看起来差别挺大,其实更第三种方式一样 ,都是在类初始化即实例化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; } }
这种方式同样利用了class loder的机制来保证初始化instance时只有一个线程,但它跟第三、四种方式不同的是:Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。
第六种(枚举):
public enum Singleton { INSTANCE; public void whateverMethod() { } }
这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过必须要JDK1.5以上。
第七种(双重校验锁):
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; } }
转载请注明:零五宝典 » 《JAVA设计模式》——单例模式及其七种写法