饿汉式单例与懒汉式单例模式
饿汉式和懒汉式是单例模式(Singleton Pattern)的两种常见实现方式。单例模式确保一个类只有一个实例,并提供该实例的全局访问点。这两种方式主要在实例创建的时机上有所不同。以下是对这两种方式的详细解释:
饿汉式单例
特点:
- 立即加载:在类加载时就创建单例实例。
- 线程安全:由于实例在类加载时即被创建,因此不存在多线程环境下实例重复创建的问题。
- 资源消耗:即使单例实例可能很久之后才会被使用,甚至有可能不被使用,也会提前占用资源。
实现方式:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
// 构造函数私有化,防止外部实例化
}
public static Singleton getInstance() {
return instance;
}
}
懒汉式单例
特点:
- 延迟加载:只有在首次需要使用时才创建实例。
- 非线程安全(无同步处理时):在多线程环境下,如果不进行同步控制,可能会导致多个实例被创建。
- 资源节约:实例只有在需要时才创建,因此不会占用不必要的资源。
实现方式(基本形式,非线程安全):
public class Singleton {
private static Singleton instance;
private Singleton() {
// 构造函数私有化,防止外部实例化
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全实现(双重检查锁定):
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;
}
}
比较
- 实现难度:饿汉式实现简单,懒汉式需要考虑线程安全问题。
- 性能:饿汉式不需要加锁,性能较高。懒汉式在某些实现中需要同步,可能影响性能。
- 资源:饿汉式会提前占用资源,适用于实例创建成本不高的场景。懒汉式则只在需要时创建实例,适合实例创建成本较高且使用频率较低的场合。
选择哪种方式取决于具体应用场景的需求,资源使用、性能需求、以及线程安全性等因素。