单例模式的几种实现方式

单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。单例模式也叫单态模式。

通常单例模式在 Java 语言中,有两种构建方式:

  • 懒汉式。指全局的单例实例在第一次被使用时构建。
  • 饿汉式。指全局的单例实例在类装载时构建。

以下方式均线程安全

懒汉式 (static)

不高效,因为在任何时候只能有一个线程调用 getInstance() 方法。但是同步操作只需要在 instance == null 调用时才被需要,即第一次创建单例实例对象时。双重检验锁改进。

public class Singleton {
private static Singleton instance;

private Singleton() {
}

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

懒汉式 (static) | 双重检验锁 (double checked locking pattern)

两次检查 instance == null,一次是在同步块外,一次是在同步块内。因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例。volatile 保证 instance = new Singleton() 的顺序性。

public class Singleton {
private static volatile Singleton instance;

private Singleton() {
}

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

懒汉式 (static) | 静态内部类 (static nested class)

推荐。

public class Singleton {

private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}

private Singleton() {
}

public static Singleton getInstance() {
return SingletonHolder.instance;
}
}

饿汉式 (static final)

是一种懒加载模式 (lazy initialization)。单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance() 方法。

public class Singleton {
private static final Singleton instance = new Singleton();

private Singleton() {
}

public static Singleton getInstance() {
return instance;
}
}

枚举式 (Enum)

最简单。

public enum Singleton {
INSTANCE;
}

总结

这篇博文只是自己梳理了一遍,有时间再完善完善。

参考资料

DeppWang wechat
个人公众号