五大创建型设计模式:
单例模式,策略模式,观察者模式,工厂模式,原型模式
一、单例模式(Singleton Pattern)详解
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。它常用于需要全局唯一对象的场景,如配置管理、线程池、数据库连接池等。
1. 单例模式的核心原则
私有化构造函数:禁止外部通过 new 创建实例。
静态方法提供全局访问点:通过类方法获取唯一实例。
线程安全:确保在多线程环境下仍只生成一个实例。
2. 单例模式的实现方式
2.1 懒汉式(Lazy Initialization)
特点:实例在第一次使用时创建,延迟加载节省资源,但需处理线程安全。
问题:多线程环境下可能破坏单例。
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} // 私有构造函数
// 线程不安全!多线程可能创建多个实例
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
2.2 线程安全的懒汉式(Synchronized Method)
通过synchronized加锁解决线程安全问题,但性能较低。
缺点:锁粒度粗,每次调用getInstance()都需同步。
public class SynchronizedSingleton {
private static SynchronizedSingleton instance;
private SynchronizedSingleton() {}
// 线程安全,但每次访问都要加锁,性能差
public static synchronized SynchronizedSingleton getInstance() {
if (instance == null) {
instance = new SynchronizedSingleton();
}
return instance;
}
}
2.3 双重检查锁定(Double-Checked Locking)
优化:减少锁的粒度,仅在第一次创建时同步。
关键点:volatile禁止JVM指令重排序,确保对象完全初始化后再赋值。
双重检查(两次if (instance == null))避免多线程重复创建。
public class DCLSingleton {
private static volatile DCLSingleton instance; // volatile防止指令重排序
private DCLSingleton() {}
public static DCLSingleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (DCLSingleton.class) { // 加锁
if (instance == null) { // 第二次检查
instance = new DCLSingleton(); // 初始化
}
}
}
return instance;
}
}
2.4 饿汉式(Eager Initialization)
特点:类加载时立即初始化实例,线程安全但可能浪费资源。
优点:实现简单,线程安全。
缺点:无论是否使用都会创建实例,可能占用内存。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2.5 静态内部类(Holder Pattern)
特点:延迟加载 + 线程安全,无锁实现高性能。
原理:JVM保证类加载的线程安全性。
静态内部类SingletonHolder在首次调用getInstance()时加载,触发实例创建。
public class HolderSingleton {
private HolderSingleton() {}
// 静态内部类在第一次访问时加载
private static class SingletonHolder {
private static final HolderSingleton INSTANCE = new HolderSingleton();
} public static HolderSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
2.6 枚举单例(Enum Singleton)
特点:
最简洁安全的实现,天然防反射和序列化攻击
线程安全。
自动处理序列化和反序列化。
反射无法破坏单例。
public enum EnumSingleton {
INSTANCE; // 单例实例
public void doSomething() {
System.out.println("Singleton method");
}
}
// 使用方式
EnumSingleton.INSTANCE.doSomething();
对比