40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?

server/2025/3/4 17:51:07/

在这里插入图片描述

在Java中,单例模式(Singleton Pattern)用于确保一个类只有一个实例,并提供全局访问点。以下是详细的实现方式、适用场景及注意事项:


一、单例模式的实现方式

1. 饿汉式(Eager Initialization)

特点:类加载时立即创建实例,线程安全但可能浪费资源。

java">public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;}
}

优点:实现简单,线程安全。
缺点:实例在类加载时创建,即使未被使用。


在这里插入图片描述

2. 懒汉式(Lazy Initialization)

特点:延迟实例化,但需处理线程安全问题。

java">public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static synchronized LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}

优点:按需创建实例。
缺点:同步方法导致性能下降。


3. 双重检查锁(Double-Checked Locking)

特点:减少同步开销,需使用volatile防止指令重排。

java">public class DCLSingleton {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;}
}

优点:兼顾线程安全和性能。
缺点:实现较复杂,需注意JDK版本兼容性。


4. 静态内部类(Static Inner Class)

特点:利用类加载机制保证线程安全。

java">public class InnerClassSingleton {private InnerClassSingleton() {}private static class Holder {static final InnerClassSingleton instance = new InnerClassSingleton();}public static InnerClassSingleton getInstance() {return Holder.instance;}
}

优点:延迟加载,线程安全,无需同步。
缺点:无法通过参数初始化实例。


5. 枚举单例(Enum Singleton)

特点:由JVM保证唯一性,防止反射和序列化破坏。

java">public enum EnumSingleton {INSTANCE;public void doSomething() {// 方法实现}
}

优点:天然线程安全,防反射和序列化攻击。
缺点:无法继承其他类,不够灵活。


在这里插入图片描述

二、单例模式的使用场景

  1. 全局配置管理
    例如,系统配置类需要全局唯一实例,确保配置一致。

  2. 日志记录器
    统一管理日志输出,避免多个实例导致资源竞争。

  3. 数据库连接池
    维护唯一的连接池实例,高效管理数据库连接。

  4. 缓存系统
    缓存数据需要全局访问,避免重复创建缓存实例。

  5. 硬件资源访问
    如打印机服务,需统一调度硬件资源。


三、注意事项与潜在问题

  1. 线程安全
    懒汉式需通过同步或双重检查锁确保线程安全。

  2. 反射攻击
    普通单例可能被反射调用构造函数,需在构造器中添加防护:

    java">private Singleton() {if (instance != null) {throw new IllegalStateException("Instance already exists");}
    }
    
  3. 序列化与反序列化
    实现Serializable接口时,需重写readResolve方法:

    java">protected Object readResolve() {return getInstance();
    }
    
  4. 测试困难
    单例的全局状态可能导致测试耦合,可通过依赖注入(如Spring容器管理)解耦。

  5. 过度使用
    滥用单例会提高代码耦合度,应仅在需要严格唯一实例时使用。


在这里插入图片描述

四、总结

实现方式线程安全延迟加载防反射防序列化适用场景
饿汉式简单场景,实例轻量
懒汉式(同步)需要延迟加载,性能不敏感
双重检查锁高性能要求的延迟加载
静态内部类推荐的延迟加载方式
枚举高安全性要求(推荐方式)

最佳实践

  • 优先选择枚举单例静态内部类实现。
  • 避免通过单例传递全局状态,尽量依赖接口编程。
  • 在框架(如Spring)中,尽量使用容器管理的单例Bean而非手动实现。

通过合理选择实现方式,单例模式能有效管理全局资源,但需谨慎使用以避免设计上的陷阱。


http://www.ppmy.cn/server/172391.html

相关文章

WeakAuras Lua Script TOC

十字军的试炼,刺骨之寒,插件,团队高亮提示 WA-Script字符串: !WA:2!TRZAZTX11PLWVeKJJinRQTIscmTScPenkbPeRTNWKcqckbl(YaGKY6XaSl2lWUwG7UE3f8HsDQnRQTCDSDmRJTgBpojCC80jXX2f2v2wtI)G6FGZWPJh2V0pOXK2AM(KTnoTnzCp37DxGfGlOivt…

【子网掩码计算器:Python + Tkinter 实现】

子网掩码计算器:Python Tkinter 实现 引言代码功能概述代码实现思路1. 界面设计2. 功能实现3. 事件处理 子网掩码计算器实现步骤1. 导入必要的库2. 定义主窗口类 SubnetCalculatorApp3. 创建菜单栏4. 创建界面组件5. 判断 IP 地址类别6. 计算子网信息7. 其他功能函…

leetcode 76. 最小覆盖子串

题目如下 数据范围 首先本题可以利用不定长的滑动窗口思想不断枚举右端同时检查窗口是否符合题意。 但是这样做每次新枚举一个窗口都要检查造成了很多重复计算。 我们发现其实每次变化要么是少一个字符要么是多一个字符而中间的根本没变。 所以,我们令字符串t出…

Linux:TCP和守护进程

一、TCP网络程序 1.1 TCP服务端 成员变量: int _listensock; // 监听的文件描述符 string _ip; // 服务端ip uint16_t _port; // 端口号 bool _isrunning; // 服务器是否在运行 1.1.1 InitServer-创建服务端 1、创建套接字socket socket()打开一个网络通讯端…

【软件测试】_selenium自动化测试:定位元素与点击元素

目录 1. CSS定位与XPath定位 1.1 以百度搜索栏和百度一下按钮了解元素定位 1.2 关于CSS和XPath位置的获取方法 2. 以输出百度热搜词条文本为例使用元素定位 2.1 使用开发者页面获取目标元素的CSS或XPath位置 2.2 使用selenium编写自动测试代码 2.3 查看自动测试结果 3. …

机器学习数学基础:35.效度

效度全攻略:从理论到实践的深度剖析 一、效度(Validity)入门:揭开精准测量的面纱 效度,简单来说,就是测量工具能否准确命中目标的“命中率”。想象你手中有一把枪(测量工具)&#…

C++ MySQL ORM接口设计优化:从宏污染到现代流式API

(基于编译期反射与链式调用的ORM框架重构实践) 在C中设计一个优雅的MySQL ORM接口,既要兼顾易用性,又要保障性能与类型安全。 本文针对开发者常见的宏污染、元数据冗余、API臃肿等问题,结合现代C特性提出一套优化方案…

2022java面试总结,1000道(集合+JVM+并发编程+Spring+Mybatis)的Java高频面试题

1、面试题模块汇总 面试题包括以下十九个模块: Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下图所示…