Java设计模式之单例模式(七种写法)
第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作:
public class Singleton { private static Singleton instance; private Singleton (){}//私有化构造方法,防止类被实例化 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
第二种,懒汉式,lazy初始化,线程安全:
- 优点:第一次调用才初始化,避免内存浪费。
- 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
第三种,饿汉式,不是lazy初始化,线程安全:
- 优点:没有加锁,执行效率会提高。
- 缺点:类加载时就初始化,浪费内存。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
第四种,饿汉式,lazy初始化,线程安全:
public class Singleton { private Singleton instance = null; static { instance = new Singleton(); } private Singleton (){} public static Singleton getInstance() { return this.instance; } }
第五种,静态内部类,lazy初始化,线程安全:
区别第三种,Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用;只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 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; } }
第六种(枚举),不是lazy初始化,线程安全:
public enum Singleton { INSTANCE; public void whateverMethod() { } }
第七种,双重校验锁DCL(double-checked locking),lazy初始化,线程安全:
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; } }