饿汉式
- 代码实现:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
- 优点:
- 线程安全,因为类加载时就创建实例,不存在多线程创建实例的问题。
- 实现简单,代码量少。
- 缺点:
- 资源浪费,不管是否使用这个单例,类加载时就会创建实例。
- 不支持延迟加载,如果单例创建开销大且长时间不用,会造成性能浪费。
静态内部类方式
- 代码实现:
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 优点:
- 线程安全,利用了类加载机制保证实例的唯一性。
- 支持延迟加载,只有在调用
getInstance()
方法时,才会加载SingletonHolder
类并创建实例。
- 性能较好,没有额外的同步开销。
- 缺点:
双重检查锁(DCL)方式
- 代码实现:
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;
}
}
- 优点:
- 支持延迟加载,提高了资源利用率。
- 性能较高,只有第一次创建实例时会有同步开销,后续调用直接返回实例。
- 缺点:
- 实现复杂,需要注意
volatile
关键字的使用,防止指令重排导致的空指针异常。
- 在高并发场景下,
synchronized
同步块会有一定的性能开销,虽然相比其他同步方式已经优化。