这里有两种实现方式,双重检查锁定(DCL)或静态内部类
DCL
public class Singleton { private static volatile Singleton instance; private Singleton() { if (instance != null) { throw new RuntimeException("Use getInstance() method to get the single instance"); } } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
|
当第一次检查发现实例为null时,进入同步块,确保只有一个线程能进入创建实例的代码
静态内部类
public class Singleton { private Singleton() { if (SingletonHolder.INSTANCE != null) { throw new RuntimeException("Use getInstance() method to get the single instance"); } } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
|
JVM在类加载阶段会加锁,保证一个类只被加载一次,静态内部类SingletonHolder
只有在被主动使用时才会加载,由JVM保证INSTANCE
只被初始化一次
外部类加载时不会立即加载内部类,只有当调用getInstance()
时才会触发SingletonHolder
的加载