中国建设银行网站 个人,百度关键词推广工具,建筑类专业做教育的网站,wordpress当前文章所属分类引言#xff1a;为什么需要单例模式
在软件开发中#xff0c;某些对象只需要一个全局实例#xff1a;
数据库连接池配置管理器日志记录器线程池缓存系统
使用new关键字多次创建这些对象会导致#xff1a; #mermaid-svg-TyfdXbNvcmqwnA6C {font-family:trebuchet m…引言为什么需要单例模式
在软件开发中某些对象只需要一个全局实例
数据库连接池配置管理器日志记录器线程池缓存系统
使用new关键字多次创建这些对象会导致 #mermaid-svg-TyfdXbNvcmqwnA6C {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .error-icon{fill:#552222;}#mermaid-svg-TyfdXbNvcmqwnA6C .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TyfdXbNvcmqwnA6C .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-TyfdXbNvcmqwnA6C .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TyfdXbNvcmqwnA6C .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TyfdXbNvcmqwnA6C .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TyfdXbNvcmqwnA6C .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TyfdXbNvcmqwnA6C .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TyfdXbNvcmqwnA6C .marker.cross{stroke:#333333;}#mermaid-svg-TyfdXbNvcmqwnA6C svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TyfdXbNvcmqwnA6C .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .cluster-label text{fill:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .cluster-label span{color:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .label text,#mermaid-svg-TyfdXbNvcmqwnA6C span{fill:#333;color:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .node rect,#mermaid-svg-TyfdXbNvcmqwnA6C .node circle,#mermaid-svg-TyfdXbNvcmqwnA6C .node ellipse,#mermaid-svg-TyfdXbNvcmqwnA6C .node polygon,#mermaid-svg-TyfdXbNvcmqwnA6C .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TyfdXbNvcmqwnA6C .node .label{text-align:center;}#mermaid-svg-TyfdXbNvcmqwnA6C .node.clickable{cursor:pointer;}#mermaid-svg-TyfdXbNvcmqwnA6C .arrowheadPath{fill:#333333;}#mermaid-svg-TyfdXbNvcmqwnA6C .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TyfdXbNvcmqwnA6C .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TyfdXbNvcmqwnA6C .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-TyfdXbNvcmqwnA6C .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-TyfdXbNvcmqwnA6C .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TyfdXbNvcmqwnA6C .cluster text{fill:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C .cluster span{color:#333;}#mermaid-svg-TyfdXbNvcmqwnA6C div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TyfdXbNvcmqwnA6C :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 多次创建 资源浪费 状态不一致 并发冲突 单例模式正是为解决这类问题而生的设计模式。它确保一个类只有一个实例并提供全局访问点。本文将深入剖析单例模式的原理、实现及高级应用场景。 一、模式定义与核心思想
1.1 官方定义 单例模式 (Singleton Pattern)确保一个类只有一个实例并提供一个全局访问点。 1.2 设计哲学 #mermaid-svg-caZWHHJdBgFtzuNf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .error-icon{fill:#552222;}#mermaid-svg-caZWHHJdBgFtzuNf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-caZWHHJdBgFtzuNf .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-caZWHHJdBgFtzuNf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-caZWHHJdBgFtzuNf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-caZWHHJdBgFtzuNf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-caZWHHJdBgFtzuNf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-caZWHHJdBgFtzuNf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-caZWHHJdBgFtzuNf .marker.cross{stroke:#333333;}#mermaid-svg-caZWHHJdBgFtzuNf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-caZWHHJdBgFtzuNf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .cluster-label text{fill:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .cluster-label span{color:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .label text,#mermaid-svg-caZWHHJdBgFtzuNf span{fill:#333;color:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .node rect,#mermaid-svg-caZWHHJdBgFtzuNf .node circle,#mermaid-svg-caZWHHJdBgFtzuNf .node ellipse,#mermaid-svg-caZWHHJdBgFtzuNf .node polygon,#mermaid-svg-caZWHHJdBgFtzuNf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-caZWHHJdBgFtzuNf .node .label{text-align:center;}#mermaid-svg-caZWHHJdBgFtzuNf .node.clickable{cursor:pointer;}#mermaid-svg-caZWHHJdBgFtzuNf .arrowheadPath{fill:#333333;}#mermaid-svg-caZWHHJdBgFtzuNf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-caZWHHJdBgFtzuNf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-caZWHHJdBgFtzuNf .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-caZWHHJdBgFtzuNf .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-caZWHHJdBgFtzuNf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-caZWHHJdBgFtzuNf .cluster text{fill:#333;}#mermaid-svg-caZWHHJdBgFtzuNf .cluster span{color:#333;}#mermaid-svg-caZWHHJdBgFtzuNf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-caZWHHJdBgFtzuNf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 客户端 单例实例 客户端 客户端 核心原则
私有构造器防止外部实例化静态实例全局唯一实例全局访问点提供获取实例的方法 二、单例模式实现方式大全
2.1 实现方案对比
实现方式线程安全延迟加载序列化安全反射安全复杂度饿汉式是否否否★☆☆懒汉式(非线程安全)否是否否★☆☆同步方法是是否否★★☆双重检查锁是是否否★★★静态内部类是是否否★★☆枚举是否是是★☆☆
2.2 饿汉式Eager Initialization
public class EagerSingleton {// 类加载时即初始化private static final EagerSingleton INSTANCE new EagerSingleton();// 私有构造器private EagerSingleton() {}// 全局访问点public static EagerSingleton getInstance() {return INSTANCE;}
}特点
线程安全JVM保证类加载的线程安全不支持延迟加载简单直接
2.3 懒汉式Lazy Initialization - 非线程安全
public class UnsafeLazySingleton {private static UnsafeLazySingleton instance;private UnsafeLazySingleton() {}public static UnsafeLazySingleton getInstance() {if (instance null) {instance new UnsafeLazySingleton();}return instance;}
}风险多线程环境下可能创建多个实例
2.4 同步方法Thread-Safe Lazy
public class SynchronizedSingleton {private static SynchronizedSingleton instance;private SynchronizedSingleton() {}// 同步方法保证线程安全public static synchronized SynchronizedSingleton getInstance() {if (instance null) {instance new SynchronizedSingleton();}return instance;}
}缺点每次获取实例都需要同步性能差
2.5 双重检查锁Double-Checked Locking
public class DCLSingleton {// volatile保证可见性和有序性private static volatile DCLSingleton instance;private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance null) { // 第一次检查synchronized (DCLSingleton.class) {if (instance null) { // 第二次检查instance new DCLSingleton();}}}return instance;}
}关键点
volatile防止指令重排序两次判空减少同步开销
2.6 静态内部类Initialization-on-demand Holder
public class HolderSingleton {private HolderSingleton() {}// 静态内部类持有实例private static class SingletonHolder {static final HolderSingleton INSTANCE new HolderSingleton();}public static HolderSingleton getInstance() {return SingletonHolder.INSTANCE;}
}原理利用类加载机制保证线程安全实现延迟加载
2.7 枚举Enum Singleton - 最佳实践
public enum EnumSingleton {INSTANCE;// 业务方法public void businessMethod() {System.out.println(Singleton business logic);}
}优势
线程安全序列化安全反射安全简洁明了 三、单例模式进阶挑战
3.1 序列化与反序列化安全
public class SerializableSingleton implements Serializable {private static final long serialVersionUID 1L;private static SerializableSingleton instance new SerializableSingleton();private SerializableSingleton() {}public static SerializableSingleton getInstance() {return instance;}// 防止反序列化创建新实例protected Object readResolve() {return instance;}
}3.2 反射攻击防护
public class ReflectionProofSingleton {private static ReflectionProofSingleton instance;private ReflectionProofSingleton() {// 防止反射创建实例if (instance ! null) {throw new IllegalStateException(Singleton already initialized);}}public static synchronized ReflectionProofSingleton getInstance() {if (instance null) {instance new ReflectionProofSingleton();}return instance;}
}3.3 克隆安全
public class CloneSafeSingleton implements Cloneable {private static CloneSafeSingleton instance new CloneSafeSingleton();private CloneSafeSingleton() {}public static CloneSafeSingleton getInstance() {return instance;}Overrideprotected Object clone() throws CloneNotSupportedException {throw new CloneNotSupportedException(Singleton cannot be cloned);}
}四、多线程环境下的单例
4.1 性能对比测试
barCharttitle 单例模式性能对比1000万次获取x-axis 实现方式y-axis 时间(ms)series 耗时EagerSingleton: 32EnumSingleton: 35HolderSingleton: 38DCLSingleton: 45SynchronizedSingleton: 12004.2 单例与线程池
public class ThreadPoolSingleton {private static final int CORE_POOL_SIZE 5;private static volatile ExecutorService instance;private ThreadPoolSingleton() {}public static ExecutorService getInstance() {if (instance null) {synchronized (ThreadPoolSingleton.class) {if (instance null) {instance new ThreadPoolExecutor(CORE_POOL_SIZE,CORE_POOL_SIZE,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue());}}}return instance;}
}4.3 分布式环境挑战 #mermaid-svg-EiPPNzwv8cS03foH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-EiPPNzwv8cS03foH .error-icon{fill:#552222;}#mermaid-svg-EiPPNzwv8cS03foH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EiPPNzwv8cS03foH .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-EiPPNzwv8cS03foH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EiPPNzwv8cS03foH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EiPPNzwv8cS03foH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EiPPNzwv8cS03foH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EiPPNzwv8cS03foH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EiPPNzwv8cS03foH .marker.cross{stroke:#333333;}#mermaid-svg-EiPPNzwv8cS03foH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EiPPNzwv8cS03foH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EiPPNzwv8cS03foH .cluster-label text{fill:#333;}#mermaid-svg-EiPPNzwv8cS03foH .cluster-label span{color:#333;}#mermaid-svg-EiPPNzwv8cS03foH .label text,#mermaid-svg-EiPPNzwv8cS03foH span{fill:#333;color:#333;}#mermaid-svg-EiPPNzwv8cS03foH .node rect,#mermaid-svg-EiPPNzwv8cS03foH .node circle,#mermaid-svg-EiPPNzwv8cS03foH .node ellipse,#mermaid-svg-EiPPNzwv8cS03foH .node polygon,#mermaid-svg-EiPPNzwv8cS03foH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EiPPNzwv8cS03foH .node .label{text-align:center;}#mermaid-svg-EiPPNzwv8cS03foH .node.clickable{cursor:pointer;}#mermaid-svg-EiPPNzwv8cS03foH .arrowheadPath{fill:#333333;}#mermaid-svg-EiPPNzwv8cS03foH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EiPPNzwv8cS03foH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EiPPNzwv8cS03foH .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-EiPPNzwv8cS03foH .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-EiPPNzwv8cS03foH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EiPPNzwv8cS03foH .cluster text{fill:#333;}#mermaid-svg-EiPPNzwv8cS03foH .cluster span{color:#333;}#mermaid-svg-EiPPNzwv8cS03foH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EiPPNzwv8cS03foH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务A Redis/ZooKeeper 服务B 解决方案
使用分布式锁实现全局单例依赖外部存储维护状态 五、单例模式应用场景
5.1 典型应用场景
场景单例应用优势配置管理全局配置读取统一配置源日志系统日志记录器避免重复创建数据库连接连接池管理资源复用缓存系统全局缓存数据一致性硬件接口设备控制避免冲突
5.2 使用时机判断
当满足以下条件时考虑单例模式
类需要全局唯一实例需要严格控制资源访问需要共享状态或数据需要频繁访问的对象
5.3 不适用场景
需要多实例的类需要扩展的子类测试驱动开发难以模拟分布式系统需特殊处理 六、模式优劣辩证
6.1 优势 ✅ #mermaid-svg-SqvHOjelltYSJYWn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SqvHOjelltYSJYWn .error-icon{fill:#552222;}#mermaid-svg-SqvHOjelltYSJYWn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SqvHOjelltYSJYWn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-SqvHOjelltYSJYWn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SqvHOjelltYSJYWn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SqvHOjelltYSJYWn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SqvHOjelltYSJYWn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SqvHOjelltYSJYWn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SqvHOjelltYSJYWn .marker.cross{stroke:#333333;}#mermaid-svg-SqvHOjelltYSJYWn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SqvHOjelltYSJYWn .pieCircle{stroke:black;stroke-width:2px;opacity:0.7;}#mermaid-svg-SqvHOjelltYSJYWn .pieTitleText{text-anchor:middle;font-size:25px;fill:black;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-SqvHOjelltYSJYWn .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#333;font-size:17px;}#mermaid-svg-SqvHOjelltYSJYWn .legend text{fill:black;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-SqvHOjelltYSJYWn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 35% 25% 20% 15% 5% 单例模式优势 资源优化 状态一致性 全局访问 避免重复创建 减少内存占用 6.2 劣势 ❌
违反单一职责兼具创建和管理功能测试困难难以模拟和替换隐藏依赖增加耦合度并发挑战需要额外处理线程安全生命周期管理何时销毁实例 七、单例模式与依赖注入
7.1 单例 vs 依赖注入容器 #mermaid-svg-jPTfsAa20oUESYKx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jPTfsAa20oUESYKx .error-icon{fill:#552222;}#mermaid-svg-jPTfsAa20oUESYKx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jPTfsAa20oUESYKx .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-jPTfsAa20oUESYKx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jPTfsAa20oUESYKx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jPTfsAa20oUESYKx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jPTfsAa20oUESYKx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jPTfsAa20oUESYKx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jPTfsAa20oUESYKx .marker.cross{stroke:#333333;}#mermaid-svg-jPTfsAa20oUESYKx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jPTfsAa20oUESYKx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jPTfsAa20oUESYKx .cluster-label text{fill:#333;}#mermaid-svg-jPTfsAa20oUESYKx .cluster-label span{color:#333;}#mermaid-svg-jPTfsAa20oUESYKx .label text,#mermaid-svg-jPTfsAa20oUESYKx span{fill:#333;color:#333;}#mermaid-svg-jPTfsAa20oUESYKx .node rect,#mermaid-svg-jPTfsAa20oUESYKx .node circle,#mermaid-svg-jPTfsAa20oUESYKx .node ellipse,#mermaid-svg-jPTfsAa20oUESYKx .node polygon,#mermaid-svg-jPTfsAa20oUESYKx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jPTfsAa20oUESYKx .node .label{text-align:center;}#mermaid-svg-jPTfsAa20oUESYKx .node.clickable{cursor:pointer;}#mermaid-svg-jPTfsAa20oUESYKx .arrowheadPath{fill:#333333;}#mermaid-svg-jPTfsAa20oUESYKx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jPTfsAa20oUESYKx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jPTfsAa20oUESYKx .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-jPTfsAa20oUESYKx .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-jPTfsAa20oUESYKx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jPTfsAa20oUESYKx .cluster text{fill:#333;}#mermaid-svg-jPTfsAa20oUESYKx .cluster span{color:#333;}#mermaid-svg-jPTfsAa20oUESYKx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jPTfsAa20oUESYKx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 直接调用 注入 使用 传统单例 单例类 DI容器 客户端 单例Bean 7.2 Spring中的单例
Service // Spring默认单例作用域
public class OrderService {// 业务逻辑
}RestController
public class OrderController {private final OrderService orderService;// 通过构造器注入单例public OrderController(OrderService orderService) {this.orderService orderService;}
}7.3 最佳整合实践
public class DatabaseConnection {private static DatabaseConnection instance;private DatabaseConnection() {}public static DatabaseConnection getInstance() {if (instance null) {synchronized (DatabaseConnection.class) {if (instance null) {instance new DatabaseConnection();}}}return instance;}// 注册到Spring容器Beanpublic DatabaseConnection databaseConnection() {return DatabaseConnection.getInstance();}
}八、在开源框架中的应用
8.1 Java Runtime类
public class Runtime {private static Runtime currentRuntime new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}
}8.2 Log4j2 LoggerContext
public class LoggerContext {private static LoggerContext context;public static LoggerContext getContext() {if (context null) {synchronized (LoggerContext.class) {if (context null) {context new LoggerContext();}}}return context;}
}8.3 Spring ApplicationContext
public class AnnotationConfigApplicationContext {// 虽然不是严格单例但通常作为单例使用
}// 典型使用方式
SpringBootApplication
public class MyApp {public static void main(String[] args) {// 创建单例ApplicationContextApplicationContext context SpringApplication.run(MyApp.class, args);}
}九、单例模式反模式与陷阱
9.1 常见错误实现
// 反例1public字段暴露
public class PublicFieldSingleton {public static final PublicFieldSingleton INSTANCE new PublicFieldSingleton();private PublicFieldSingleton() {}
}// 反例2静态块未处理异常
public class StaticBlockSingleton {private static StaticBlockSingleton instance;static {try {instance new StaticBlockSingleton();} catch (Exception e) {// 未处理异常}}private StaticBlockSingleton() {}public static StaticBlockSingleton getInstance() {return instance;}
}9.2 单例滥用案例
// 反例将业务服务设计为单例
public class UserService {private static UserService instance;private UserService() {}// 单例访问点public static synchronized UserService getInstance() {if (instance null) {instance new UserService();}return instance;}// 业务方法public void registerUser(User user) {// ...}
}问题
难以扩展无法模拟测试状态污染风险 十、最佳实践指南
10.1 实现选择建议 #mermaid-svg-P9w7PfF4FcTTM4Ev {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .error-icon{fill:#552222;}#mermaid-svg-P9w7PfF4FcTTM4Ev .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-P9w7PfF4FcTTM4Ev .marker{fill:#333333;stroke:#333333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .marker.cross{stroke:#333333;}#mermaid-svg-P9w7PfF4FcTTM4Ev svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .cluster-label text{fill:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .cluster-label span{color:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .label text,#mermaid-svg-P9w7PfF4FcTTM4Ev span{fill:#333;color:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .node rect,#mermaid-svg-P9w7PfF4FcTTM4Ev .node circle,#mermaid-svg-P9w7PfF4FcTTM4Ev .node ellipse,#mermaid-svg-P9w7PfF4FcTTM4Ev .node polygon,#mermaid-svg-P9w7PfF4FcTTM4Ev .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .node .label{text-align:center;}#mermaid-svg-P9w7PfF4FcTTM4Ev .node.clickable{cursor:pointer;}#mermaid-svg-P9w7PfF4FcTTM4Ev .arrowheadPath{fill:#333333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-P9w7PfF4FcTTM4Ev .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-P9w7PfF4FcTTM4Ev .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-P9w7PfF4FcTTM4Ev .cluster text{fill:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev .cluster span{color:#333;}#mermaid-svg-P9w7PfF4FcTTM4Ev div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-P9w7PfF4FcTTM4Ev :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是 是 否 是 否 否 是 否 需要单例 需要延迟加载 需要序列化/反射安全 枚举实现 性能敏感 双重检查锁 静态内部类 需要序列化/反射安全 饿汉式 10.2 线程安全实践 优先使用不可变状态 public class ImmutableSingleton {private final MapString, String config;private ImmutableSingleton() {// 初始化后不再修改config loadConfigFromFile();}public String getConfig(String key) {return config.get(key);}
}使用ThreadLocal实现线程单例 public class ThreadLocalSingleton {private static final ThreadLocalThreadLocalSingleton instance ThreadLocal.withInitial(ThreadLocalSingleton::new);private ThreadLocalSingleton() {}public static ThreadLocalSingleton getInstance() {return instance.get();}
}10.3 测试策略
public class DatabaseConnection {private static DatabaseConnection instance;// 测试钩子static void setTestInstance(DatabaseConnection testInstance) {instance testInstance;}// 重置为生产实例static void reset() {instance null;}
}// 测试类
class DatabaseConnectionTest {AfterEachvoid tearDown() {DatabaseConnection.reset();}Testvoid testSingleton() {DatabaseConnection.setTestInstance(mock(DatabaseConnection.class));// 执行测试}
}十一、总结单例模式的核心价值
单例模式通过全局唯一实例实现了 #mermaid-svg-wDgbkoSRWXOuuZZv {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .error-icon{fill:#552222;}#mermaid-svg-wDgbkoSRWXOuuZZv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wDgbkoSRWXOuuZZv .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-wDgbkoSRWXOuuZZv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wDgbkoSRWXOuuZZv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wDgbkoSRWXOuuZZv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wDgbkoSRWXOuuZZv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wDgbkoSRWXOuuZZv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wDgbkoSRWXOuuZZv .marker.cross{stroke:#333333;}#mermaid-svg-wDgbkoSRWXOuuZZv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wDgbkoSRWXOuuZZv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .cluster-label text{fill:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .cluster-label span{color:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .label text,#mermaid-svg-wDgbkoSRWXOuuZZv span{fill:#333;color:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .node rect,#mermaid-svg-wDgbkoSRWXOuuZZv .node circle,#mermaid-svg-wDgbkoSRWXOuuZZv .node ellipse,#mermaid-svg-wDgbkoSRWXOuuZZv .node polygon,#mermaid-svg-wDgbkoSRWXOuuZZv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wDgbkoSRWXOuuZZv .node .label{text-align:center;}#mermaid-svg-wDgbkoSRWXOuuZZv .node.clickable{cursor:pointer;}#mermaid-svg-wDgbkoSRWXOuuZZv .arrowheadPath{fill:#333333;}#mermaid-svg-wDgbkoSRWXOuuZZv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wDgbkoSRWXOuuZZv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wDgbkoSRWXOuuZZv .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-wDgbkoSRWXOuuZZv .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-wDgbkoSRWXOuuZZv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wDgbkoSRWXOuuZZv .cluster text{fill:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv .cluster span{color:#333;}#mermaid-svg-wDgbkoSRWXOuuZZv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wDgbkoSRWXOuuZZv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 资源优化 提高性能 状态一致性 保证数据准确 全局访问 简化调用 设计启示 单例不是银弹而是特定场景下的精密工具 - 用对场景比实现更重要 正如《设计模式》作者GoF所强调 “单例模式确保一个类仅有一个实例并提供一个访问它的全局访问点。这个模式在需要控制资源或者协调操作时特别有用” 扩展思考 如何在微服务架构中实现全局单例单例模式如何与反应式编程结合单例对象的内存泄漏如何预防 附录单例模式快速参考卡
场景推荐实现注意事项简单应用枚举单例最佳实践首选延迟加载静态内部类简洁安全高性能要求双重检查锁需加volatile线程隔离ThreadLocal非全局单例Spring环境Bean单例利用容器管理
单例模式是构建高效、一致系统的关键工具在资源管理、配置控制等场景中具有不可替代的价值。