单例模式是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式通常用于需要在整个应用程序中共享某个资源或控制某个独占性资源的情况。
在单例模式中,通常会将类的构造函数设为私有(private),以防止外部直接实例化该类。同时,类内部会维护一个静态成员变量来保存唯一的实例,并提供一个静态方法来获取或创建这个实例。单例模式有多种实现方式,包括懒汉式、饿汉式、双重检查锁等,需要注意的是,在多线程环境下,需要考虑线程安全性,确保单例模式能够正确地工作。
懒汉式(Lazy Initialization):
懒汉式(Lazy Initialization) 懒汉式是指在第一次使用时才创建对象实例。简单来说,就是在getInstance()方法中进行判断,如果实例不存在则创建,否则直接返回已经创建的实例。
- 优点:节省内存空间,因为实例只有在需要时才会被创建。
- 缺点:在多线程环境下,如果多个线程同时调用获取实例的方法,可能会导致创建多个实例的问题,需要额外考虑线程安全性。
示例代码:
// 懒汉式单例模式
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} // 私有化构造方法
public static LazySingleton getInstance() {
if (instance == null) { // 第一次调用时创建实例
instance = new LazySingleton();
}
return instance;
}
}
饿汉式(Eager Initialization):
饿汉式(Eager Initialization) 饿汉式是指在类加载的时候就创建对象实例,因此也称为静态初始化。这种方式在多线程环境下是安全的,因为在类加载的过程中,JVM 会保证实例的唯一性。
- 优点:简单、线程安全,不需要考虑多线程环境下的同步问题。
- 缺点:可能造成资源的浪费,因为实例在类加载时就被创建,无论是否被使用。
示例代码:
// 饿汉式单例模式
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton(); // 在类加载时即创建实例
private EagerSingleton() {} // 私有化构造方法
public static EagerSingleton getInstance() {
return instance;
}
}
双重检查锁式(Double-Checked Locking):
双重锁式(Double-Checked Locking) 双重锁式是对懒汉式的改进,它通过双重检查来确保在多线程环境下只创建一个实例,并且在需要时才进行实例化。
- 优点:在保证懒加载的同时,提供了较好的性能表现。
- 缺点:在早期的 Java 版本中存在一些问题,需要额外注意实现细节。
示例代码:
// 双重锁式单例模式
public class DoubleCheckedLockingSingleton {
private volatile static DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {} // 私有化构造方法
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) { // 双重检查加锁
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}