在 Java 后端开发中, 设计模式几乎是绕不开的话题。
不论是日常业务开发、系统重构,还是技术面试,设计模式都会被反复提及。

但很多时候,我们停留在“知道名字、会背定义”,却说不清楚:

  • 这个模式 为什么要用?
  • 什么时候用才合适?
  • 在真实项目中 到底解决了什么问题?

一、什么是 Java 中的单例模式(Singleton)

1️⃣ 定义

单例模式是一种创建型设计模式,其核心目标是:

保证一个类在 JVM 中只有一个实例,并提供一个全局访问点。

通俗理解就是:

  • 这个类只能创建一个对象
  • 对象由自己控制创建
  • 外部通过统一入口访问

二、Java 中常见的单例实现方式

1、饿汉式(线程安全)

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

优点

  • 实现简单
  • 天然线程安全

缺点

  • 类加载时就创建实例
  • 如果对象创建成本高,可能造成资源浪费

2、懒汉式(双重检查锁,推荐)

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

关键点说明:

  • volatile 防止指令重排
  • 双重 if 判断减少不必要的同步开销

这是企业级项目中非常常见的一种写法


3、静态内部类(最优雅)

public class Singleton {
    private Singleton() {}

    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

特点:

  • 懒加载
  • 线程安全
  • 无需显式加锁,性能好

在很多场景下,这是综合性最优的单例实现方式。


4、枚举单例(最安全)

public enum Singleton {
    INSTANCE;
}

优点:

  • 天然防反射
  • 天然防反序列化
  • 《Effective Java》官方推荐

不足:

  • 不够灵活
  • 不适合复杂初始化逻辑

三、单例模式在真实项目中的使用场景

1️⃣ Spring 中的单例 Bean

@Service
public class UserService {
}
  • Spring 默认 scope = singleton
  • 容器中只存在一个实例
  • 所有请求共享该对象

这其实是我们每天都在使用、却容易忽略的单例模式。


2️⃣ 数据库连接池 / 线程池

DataSource dataSource;
ExecutorService executorService;

使用单例的原因很明确:

  • 创建成本高
  • 需要全局共享
  • 需要统一管理资源

频繁创建只会带来性能和稳定性问题。


3️⃣ 工具类 / 管理类

LogManager
ConfigManager
RedisClient

例如:

  • Redis 客户端管理
  • MinIO Client
  • MQ Producer / Consumer 管理器

这些类通常:

  • 不保存业务状态
  • 被多个模块复用
  • 非常适合单例模式

4️⃣ JVM 级别资源

Runtime.getRuntime();

典型代表包括:

  • Runtime
  • System
  • Logger

这些都是 JVM 级别的全局唯一资源。


四、单例模式的优缺点总结

✅ 优点

  • 减少对象创建,节省内存
  • 统一管理共享资源
  • 使用方便,全局可访问

❌ 缺点

  • 隐式依赖,不利于单元测试
  • 容易膨胀为“上帝类”
  • 多线程场景下实现复杂

单例模式不是银弹,关键在于是否用在合适的地方。


五、除了单例,还有哪些常见设计模式?

创建型模式

模式使用场景
Singleton全局唯一实例
Factory封装对象创建
Abstract Factory创建产品族
Builder构建复杂对象
Prototype对象复制

结构型模式

模式使用场景
ProxyAOP、权限、事务
Decorator功能增强
Adapter接口不兼容
Facade对外统一入口
Composite树形结构

行为型模式

模式使用场景
Strategy不同算法切换
Template Method固定流程,步骤可变
Observer事件通知
Chain of Responsibility过滤器、拦截器
State状态机、流程流转

六、总结

  • 单例模式是最常见、也最容易被滥用的设计模式
  • 真正重要的不是“会写代码”,而是“知道什么时候该用”
  • 设计模式的本质是:让系统更容易维护和扩展
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐