设计模式详解:单例模式(Singleton Pattern)
·
一、单例模式概述
1.1、什么是单例模式
单例模式是软件开发中常用的一种创建型的设计模式,核心目标是确保一个类在一个系统中只有一个实例。
1.2、单例模式使用场景
- 日志记录器(Logger)
- 线程池(ThreadPool)
- 配置管理器(Configuration Manager)
- 缓存(Cache)
- 数据库连接池
1.3、单例模式要点
- 私有化构造方法 防止外部程序new 出类的实例
- 私有的静态类实例变量
- 公共的返回静态类实例的方法
二、单例模式的创建
1.1、饿汉式创建单例模式
优点
线程安全
实现简单
缺点
类加载就创建,可能造成资源浪费
/**
* 饿汉式单例模式
*
* @author LS
* @version 1.0
* @createDate 2025/8/17 18:50
**/
public class Singleton01 {
private static final Singleton01 instance =new Singleton01();
private Singleton01() {
}
public static Singleton01 getInstance() {
return instance;
}
}
1.2、懒汉式创建单例模式
优点
延迟加载,不会造成资源浪费
缺点
多线程环境下可能创建多个实例-不推荐使用
/**
* 懒汉式创建单例模式
*
* @author LS
* @version 1.0
* @createDate 2025/8/17 19:02
**/
public class Singleton02 {
private static Singleton02 instance;
private Singleton02(){};
public static Singleton02 getInstance() {
if (instance==null){
instance=new Singleton02();
}
return instance;
}
}
1.3、懒汉式+同步方法
优点
线程安全
避免资源浪费
缺点
性能较差
/**
* 懒汉式 + 同步方法(线程安全但性能差)
*
* @author LS
* @version 1.0
* @createDate 2025/8/17 19:07
**/
public class Singleton03 {
private static Singleton03 instance;
private Singleton03(){};
public static synchronized Singleton03 getInstance(){
if (instance==null){
instance=new Singleton03();
}
return instance;
}
}
1.4、双重检查锁定(Double-Checked Locking)创建
优点 推荐使用
线程安全、延时加载、性能高
/**
* 双重检查锁定 创建单例模式
*
* @author LS
* @version 1.0
* @createDate 2025/8/17 19:15
**/
public class Singleton04 {
// 使用 volatile 防止指令重排序
private static volatile Singleton04 instance;
private Singleton04(){}
public static Singleton04 getInstance(){
if (instance==null){
synchronized (Singleton.class){
if (instance==null){
instance=new Singleton04();
}
}
}
return instance;
}
}
1.5、枚举类创建单例模式
优点:
天生线程安全
防止反射攻击(private 构造函数可被反射破坏,但枚举不行)
防止反序列化创建新实例
代码极简
Joshua Bloch(《Effective Java》作者)推荐使用枚举实现单例。
/**
* 枚举类创建单例模式
*
* @author LS
* @version 1.0
* @createDate 2025/8/2 20:29
**/
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("单例测试");
}
}
单例模式的创建还有好多,掌握上面几种在开发和面试中基本够了,接下来分享Spring中使用单例模式的案例。
三、经典的单例模式使用案例之Spring单例模式分析
3.1、Spring 单例的核心实现机制
核心类:DefaultSingletonBeanRegistry
核心数据结构:ConcurrentHashMap<String, Object>
- 这个
Map就是 Spring 单例池(俗称“单例缓存”)。 - 所有创建好的单例 Bean 都会被放入这个 Map 中,key 是 beanName,value 是 Bean 实例。
- 下次获取时直接从 Map 中取,保证唯一性。
3.2、单例创建流程(简化版)
当调用 applicationContext.getBean("xxx") 时,Spring 内部执行如下逻辑:
// 伪代码,源自 DefaultSingletonBeanRegistry.getSingleton()
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 1. 先尝试从缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 2. 同步块,防止并发创建
synchronized (this.singletonObjects) {
// 再次检查(Double-Check)
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 3. 使用工厂创建实例
singletonObject = singletonFactory.getObject();
// 4. 创建完成后放入缓存
this.singletonObjects.put(beanName, singletonObject);
}
}
}
return singletonObject;
}
这正是 “双重检查 + 缓存” 的典型单例实现!
四、结语
单例模式看似简单,但背后涉及类加载机制、线程安全、JVM 内存模型、反射、序列化等多个 Java 核心知识点。掌握它,不仅能写出高质量代码,还能在面试中脱颖而出。
更多推荐
所有评论(0)