Java单例设计模式详解

发布于:2025-03-28 ⋅ 阅读:(34) ⋅ 点赞:(0)

🌟单例模式核心指南:饿汉式VS懒汉式,看完秒变“架构师”!(开玩笑哈)🌟

📣 开场白:
"面试被吊打?项目代码混乱?你可能栽在了单例模式上!" —— 设计模式中最简单却最易踩坑的单例模式,今天用5分钟带你聊一聊!


一、🔥 先导课:3分钟搞懂设计模式

1.1 什么是设计模式?
  • � 官方定义:前辈们总结的代码复用/可维护/可扩展的经典解决方案(就像数学公式)

  • 🎯 本质作用:优雅地解决特定场景下的设计难题

  • 🌰 生活类比:乐高说明书=设计模式,积木块=代码

1.2 设计模式的3大类型(速记图)
类型 特点 典型模式
创建型 对象创建的艺术 单例、工厂
结构型 类与对象的组合 适配器、代理
行为型 对象间的协作 观察者、策略

二、💎 单例模式深度解密

2.1 单例模式三连问
  • ❓ 是什么:确保类只有1个实例,并提供全局访问点

  • 💡 为什么:避免重复创建,节省资源(数据库连接池省90%内存!)

  • 🚀 何时用:需要严格控量的场景(如配置中心、日志管理器)

2.2 单例模式四大核心
  1. 私有构造器(堵死new的路)

  2. 静态实例(全局唯一)

  3. 静态获取方法(统一入口)

  4. 线程安全(重中之重!)


三、⚡ 手撕代码:饿汉式VS懒汉式

3.1 饿汉式(Eager)—— 霸道总裁型
public class EagerSingleton {
    // 类加载立即初始化(急不可耐)
    private static final EagerSingleton instance = new EagerSingleton();
    
    // 私有构造器封印
    private EagerSingleton() {}
    
    public static EagerSingleton getInstance() {
        return instance;
    }
}

✅ 优点

  • 写法简单

  • 绝对线程安全(JVM类加载机制保证)

❌ 缺点

  • 可能造成资源浪费(不用也加载)


3.2 懒汉式(Lazy)—— 精打细算型

基础版(线程不安全)

public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {  // 多个线程同时通过检查
            instance = new LazySingleton();
        }
        return instance;
    }
}

⚠️ 致命问题:多线程下可能创建多个实例!


进阶版(双重检查锁)

public class LazySingleton {
    // volatile禁止指令重排序
    private static volatile LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {  // 第一次检查
            synchronized (LazySingleton.class) {
                if (instance == null) {  // 第二次检查
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

✅ 优化点

  • 延迟加载(用时才创建)

  • 线程安全

  • 高性能(同步块只在第一次调用时触发)


四、📊 对比总结(表格速记)

维度 饿汉式 懒汉式(双重检查锁)
加载时机 类加载时立即创建 首次调用时创建
线程安全 天然安全 需双重检查锁
资源占用 可能浪费 按需加载
实现难度 简单 较复杂
适用场景 小对象/高频访问 大对象/低频访问

五、🚀 实战应用场景

  1. 配置中心(全系统共享同一配置)

  2. 数据库连接池(避免连接数爆炸)

  3. 日志记录器(统一写入日志文件)

  4. Spring默认Bean作用域(默认单例节省资源)


💡 作者说:单例看似简单,却是设计模式的试金石。理解不同实现背后的设计哲学,才能写出既优雅又健壮的代码!你更倾向饿汉式还是懒汉式?欢迎评论区Battle~