Categories
Tags
API API文档 CAS CI-CD DevOps Docker ElasticSearch Everything Git GitHub GitHub Actions HTTP客户端 Java JWT Micrometer MyBatis-Plus Prometheus Python Redis RSS Spring Spring Boot Supplier Typora uni-app Vue Web Web应用 Web开发 中间件 代码生成 任务执行 任务管理 会话管理 内存模型 分布式 前端开发 协议 后端开发 图床 字符串匹配 安全认证 容器化 局域网 工具 工具类 并发容器 并发编程 开源 微服务 搜索引擎 数据库 数据科学 数据结构 数据验证 文件处理 文件服务器 日语 正则表达式 死锁 深度学习 源码分析 爬虫 版本控制 监控 算法 线程安全 线程池 缓存 脚本 自动化 自然语言处理 虚拟线程 设计模式 语言学习 部署 锁机制 面试 项目实战 高可用
839 words
4 minutes
单例模式
1. 基本介绍
单例模式(Singleton Pattern)是一种设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来获取该实例。它主要解决的问题是如何保证某个类的实例在整个应用程序中唯一,并且能够在需要时轻松访问。
单例模式的关键点:
- 唯一性:类只能有一个实例,确保系统中只会有这个唯一的对象。
- 全局访问:提供一个全局访问点来获取该实例。通常通过一个静态方法来获取实例。
单例模式的应用场景:
- 日志记录器:全局唯一的日志工具类。
- 数据库连接池:多个线程共享一个数据库连接池。
- 线程池:线程池是全局唯一的,避免重复创建。
- 缓存管理:全局唯一的缓存对象。
2. Java 实现
1. 饿汉式(Eager Initialization)
在类加载时就创建实例,线程安全,但可能会浪费资源(如果实例未被使用)。
public class Singleton {
// 在类加载时创建实例
private static final Singleton INSTANCE = new Singleton();
// 私有构造函数,防止外部实例化
private Singleton() {}
// 提供全局访问点
public static Singleton getInstance() {
return INSTANCE;
}
}
- 优点:实现简单,线程安全。
- 缺点:如果实例未被使用,会造成资源浪费。
2. 懒汉式(Lazy Initialization)
在第一次调用 getInstance() 时创建实例,节省资源,但需要处理多线程问题。
(1)非线程安全的懒汉式:多线程环境下可能会创建多个实例
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(2)线程安全的懒汉式(加锁):每次调用 getInstance() 都会加锁,性能较差。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3. 双重检查锁(Double-Checked Locking)
在懒汉式的基础上,通过双重检查减少加锁的开销。
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;
}
}
- 优点:线程安全,且只有在第一次创建实例时加锁。
- 缺点:实现稍复杂,需要
volatile关键字防止指令重排序。
4. 静态内部类(Static Inner Class)
利用类加载机制保证线程安全,同时实现懒加载。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 优点:线程安全,懒加载,实现简单。
- 缺点:无法传递参数初始化实例。
5. 枚举(Enum)
利用枚举的特性实现单例,线程安全且防止反射攻击。
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
- 优点:线程安全,防止反射和序列化破坏单例。
- 缺点:不够灵活(如无法延迟加载)。
6. ThreadLocal 单例
为每个线程提供一个单例实例,线程间隔离。
public class ThreadLocalSingleton {
private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =
ThreadLocal.withInitial(ThreadLocalSingleton::new);
private ThreadLocalSingleton() {}
public static ThreadLocalSingleton getInstance() {
return threadLocalInstance.get();
}
}
- 优点:线程间隔离,适合线程内单例场景。
- 缺点:每个线程都有自己的实例,不是全局单例。

