Java第五篇:单例模式——饿汉式与懒汉式详解

张开发
2026/4/3 19:10:49 15 分钟阅读
Java第五篇:单例模式——饿汉式与懒汉式详解
文章目录前言:一、简单了解什么是设计模式什么是单例模式二、单例模式的实现饿汉式单例和懒汉式单例饿汉式单例:1.是什么———饿汉式单例的定义2.为什么———饿汉式单例的好处3.怎么用———饿汉式单例的用法懒汉式单例;1.是什么———懒汉式单例的定义2.为什么———懒汉式单例的好处3.怎么用———懒汉式单例的用法二者区别:总结:前言:今天我们来学习单例的相关内容,包括懒汉式单例和饿汉式单例。一、简单了解什么是设计模式在软件开发中设计模式Design Pattern是开发人员在长期实践中总结出的通用解决方案库它不是某个问题的“唯一正确答案”而是针对一类常见设计问题的可复用思路。设计模式的本质针对一类问题的可复用方案。单例模式不是“数据库连接池的最优解”而是“解决‘确保类唯一实例’问题”的标准方案。设计模式的价值 问题匹配度什么是单例模式单例模式设计模式的完美示例为什么单例模式是设计模式的绝佳案例它完美诠释了设计模式的本质“解决一类问题类唯一实例→ 提供可复用方案饿汉式/懒汉式→ 适配具体场景数据库连接池/日志系统”核心目标防止重复创建对象节省内存和资源提供全局唯一访问点如数据库连接池、配置管理保证状态一致性避免多实例导致的数据冲突那我们学习什么呢?01:解决什么问题02:怎么解决二、单例模式的实现饿汉式单例和懒汉式单例核心问题如何在保证“类唯一实例”的同时解决线程安全和延迟加载的挑战答案通过两种经典实现方式——饿汉式提前初始化与懒汉式延迟初始化我们能灵活应对不同场景需求。饿汉式单例:1.是什么———饿汉式单例的定义在类加载时即创建实例而非在首次调用getInstance()时创建。通过static final变量在类初始化阶段完成实例化确保天然线程安全无需额外同步机制。关键原理JVM 类加载过程是线程安全的static初始化会在类加载时自动执行避免了多线程竞争问题。2.为什么———饿汉式单例的好处线程安全零风险代码简洁无冗余启动即就3.怎么用———饿汉式单例的用法例如://饿汉式单例的实现步骤 public class Hungry { // 2.定义一个静态方法记住类对象 private static final Hungry instance new Hungry(); // 1.私有构造函数防止外部实例化 private Hungry() {} // 定义一个静态方法返回对象 public static Hungry getInstance() { return instance; } }如果实例创建成本高如数据库连接饿汉式会浪费资源——此时应选择懒汉式延迟初始化懒汉式单例;1.是什么———懒汉式单例的定义在首次调用getInstance()时才创建实例而非在类加载时初始化。通过双重校验锁Double-Checked Locking和volatile关键字保证线程安全避免多线程环境下重复创建实例。关键原理第一次检查避免不必要的同步实例已存在时直接返回。同步锁仅当实例为null时进入同步块。第二次检查防止同步块内实例被重复创建多线程竞争时。volatile保证确保instance的可见性防止指令重排导致的初始化问题。2.为什么———懒汉式单例的好处资源延迟初始化适用高成本对象灵活控制初始化时机✅设计模式视角懒汉式不是最优解而是针对资源敏感对象场景的精准方案——它用稍复杂的实现换取了资源效率完美契合设计模式问题-方案的匹配逻辑。3.怎么用———懒汉式单例的用法public class Lazy { // 2.定义一个类变量用于存储对象 // volatile 保证可见性防止指令重排 private static volatile Lazy instance; // 1.私有构造函数防止外部实例化 private Lazy() {} // 3.提供一个类返回对象 public static Lazy getInstance() { if (instance null) { // 第一次检查 synchronized (Lazy.class) { // 同步锁 if (instance null) { // 第二次检查 instance new Lazy(); } } } return instance; } }如果对象创建成本低如String常量懒汉式反而增加代码复杂度——此时应选择饿汉式简单高效。二者区别:特性饿汉式懒汉式初始化时机类加载时立即首次调用getInstance()延迟线程安全天然安全JVM保证通过双重校验volatile实现安全适用场景无状态对象Math、常量类高成本对象数据库连接池、API客户端资源浪费风险会提前创建不适合高成本对象按需创建无浪费代码复杂度极简5行核心代码较复杂需双重检查volatile初始化失败处理无法处理类加载失败即崩溃可在getInstance()中捕获异常总结:今天我们深入学习了单例模式的相关内容。本次分享到此结束感谢大家的观看与支持如果本内容对您有帮助欢迎点赞、收藏您的支持将是我持续创作的最大动力谢谢

更多文章