单例模式是一种创建型设计模式,旨在确保一个类只有一个实例,并提供全局访问点来获取该实例。它保证在应用程序的整个生命周期内,特定类只存在一个实例化对象。
单例模式结构
实现方式
单例模式通常可以通过以下四种方式实现:
饿汉式
在首次请求实例时创建,线程不安全,需要考虑多线程环境下的情况。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
懒汉式
在类加载时就创建实例,天生线程安全,但可能会导致资源浪费。
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
双重检查锁
在懒汉式基础上做了改进,通过加锁来确保多线程环境下的安全创建实例。
public class DoubleCheckedSingleton {
private volatile static DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {
}
public static DoubleCheckedSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
静态内部类
利用类加载机制和静态内部类特性来实现延迟加载,同时保证线程安全。
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
}
private static class SingletonHelper {
private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHelper.instance;
}
}
优点:
-
全局访问:能够在程序的任何地方访问单例对象。
-
节省资源:避免重复创建对象,节省内存和系统资源。
缺点:
-
可能引起性能问题:在某些场景下,单例模式可能成为系统性能的瓶颈。
-
难以扩展:因为单例模式一般都是全局访问的,不利于扩展和测试。
如果程序中的某个类对于所有客户端只有一个可用的实例, 可以使用单例模式。