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

[复制链接]
发表于 2025-10-22 19:10:54 | 显示全部楼层 |阅读模式

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

一、单例模式的实现方式

1. 饿汉式(Eager Initialization)

特点:类加载时立即创建实例,线程安全但大概浪费资源。
  1. public class EagerSingleton {
  2.     private static final EagerSingleton instance = new EagerSingleton();
  3.    
  4.     private EagerSingleton() {}
  5.    
  6.     public static EagerSingleton getInstance() {
  7.         return instance;
  8.     }
  9. }
复制代码
长处:实现简朴,线程安全
缺点:实例在类加载时创建,纵然未被利用。


2. 懒汉式(Lazy Initialization)

特点:耽误实例化,但需处置惩罚线程安全题目。
  1. public class LazySingleton {
  2.     private static LazySingleton instance;
  3.    
  4.     private LazySingleton() {}
  5.    
  6.     public static synchronized LazySingleton getInstance() {
  7.         if (instance == null) {
  8.             instance = new LazySingleton();
  9.         }
  10.         return instance;
  11.     }
  12. }
复制代码
长处:按需创建实例。
缺点:同步方法导致性能降落。

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

特点:镌汰同步开销,需利用volatile防止指令重排。
  1. public class DCLSingleton {
  2.     private static volatile DCLSingleton instance;
  3.    
  4.     private DCLSingleton() {}
  5.    
  6.     public static DCLSingleton getInstance() {
  7.         if (instance == null) {
  8.             synchronized (DCLSingleton.class) {
  9.                 if (instance == null) {
  10.                     instance = new DCLSingleton();
  11.                 }
  12.             }
  13.         }
  14.         return instance;
  15.     }
  16. }
复制代码
长处:分身线程安全和性能
缺点:实现较复杂,需留意JDK版本兼容性。

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

特点:利用类加载机制包管线程安全。
  1. public class InnerClassSingleton {
  2.     private InnerClassSingleton() {}
  3.    
  4.     private static class Holder {
  5.         static final InnerClassSingleton instance = new InnerClassSingleton();
  6.     }
  7.    
  8.     public static InnerClassSingleton getInstance() {
  9.         return Holder.instance;
  10.     }
  11. }
复制代码
长处:耽误加载,线程安全,无需同步。
缺点:无法通过参数初始化实例。

5. 摆列单例(Enum Singleton)

特点:由JVM包管唯一性,防止反射和序列化粉碎。
  1. public enum EnumSingleton {
  2.     INSTANCE;
  3.    
  4.     public void doSomething() {
  5.         // 方法实现
  6.     }
  7. }
复制代码
长处:天然线程安全,防反射和序列化攻击。
缺点:无法继续其他类,不敷机动。


二、单例模式的利用场景


  • 全局设置管理
    比方,体系设置类必要全局唯一实例,确保设置划一。
  • 日记记录器
    同一管理日记输出,克制多个实例导致资源竞争。
  • 数据库毗连池
    维护唯一的毗连池实例,高效管理数据库毗连。
  • 缓存体系
    缓存数据必要全局访问,克制重复创建缓存实例。
  • 硬件资源访问
    如打印机服务,需同一调治硬件资源。

三、留意事项与埋伏题目


  • 线程安全
    懒汉式需通过同步或双重查抄锁确保线程安全。
  • 反射攻击
    平凡单例大概被反射调用构造函数,需在构造器中添加防护:
    1. private Singleton() {
    2.     if (instance != null) {
    3.         throw new IllegalStateException("Instance already exists");
    4.     }
    5. }
    复制代码
  • 序列化与反序列化
    实现Serializable接口时,需重写readResolve方法:
    1. protected Object readResolve() {
    2.     return getInstance();
    3. }
    复制代码
  • 测试困难
    单例的全局状态大概导致测试耦合,可通过依靠注入(如Spring容器管理)解耦。
  • 太过利用
    滥用单例会进步代码耦合度,应仅在必要严酷唯一实例时利用。


四、总结

实现方式线程安全耽误加载防反射防序列化实用场景饿汉式✅❌❌❌简朴场景,实例轻量懒汉式(同步)✅✅❌❌必要耽误加载,性能不敏感双重查抄锁✅✅❌❌高性能要求的耽误加载静态内部类✅✅❌❌保举的耽误加载方式摆列✅❌✅✅高安全性要求(保举方式)最佳实践

  • 优先选择摆列单例静态内部类实现。
  • 克制通过单例通报全局状态,只管依靠接口编程。
  • 在框架(如Spring)中,只管利用容器管理的单例Bean而非手动实现。
通过公道选择实现方式,单例模式能有效管理全局资源,但需审慎利用以克制计划上的陷阱。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表