23种设计模式-创建型模式之单例模式(Java版本)

Java 单例模式(Singleton Pattern)详解

🌟 什么是单例模式?

单例模式确保一个类只有一个实例,并提供一个全局访问点来访问它。


🧠 使用场景

  • 配置管理类(如读取配置文件)
  • 日志工具类(如 Log4j 的 Logger)
  • 数据库连接池
  • 缓存管理
  • 线程池

✅ 实现方式(Java)

方式一:饿汉式(类加载时就实例化)

java 复制代码
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}
  • 优点:简单、线程安全
  • 缺点:类加载时就创建实例,可能浪费资源

方式二:懒汉式(线程不安全)

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 缺点:多线程环境会创建多个实例

方式三:懒汉式 + synchronized(线程安全)

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 缺点:加锁影响性能

方式四:双重检查锁(DCL)

java 复制代码
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 防止指令重排

方式五:静态内部类

java 复制代码
public class Singleton {

    private Singleton() {}

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

    public static Singleton getInstance() {
        return Holder.instance;
    }
}
  • 优点:利用 JVM 机制,线程安全 + 懒加载 + 高性能

方式六:枚举实现(最推荐)

java 复制代码
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Doing something...");
    }
}
  • 优点:防反射、防反序列化、天然线程安全
  • 缺点:不能延迟加载

🔐 防止反射与反序列化破坏单例

防反射

java 复制代码
private Singleton() {
    if (instance != null) {
        throw new RuntimeException("反射破坏单例!");
    }
}

防反序列化

java 复制代码
private Object readResolve() {
    return instance;
}

📌 各方式对比

实现方式 是否懒加载 是否线程安全 推荐度
饿汉式 ★★
懒汉式
synchronized ★★
DCL ★★★★
静态内部类 ★★★★★
枚举 ★★★★★(最安全)
相关推荐
团子的二进制世界1 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法
Max_uuc5 分钟前
【C++ 硬核】打破嵌入式 STL 禁忌:利用 std::pmr 在“栈”上运行 std::vector
开发语言·jvm·c++
故事不长丨5 分钟前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long3166 分钟前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
牵牛老人8 分钟前
【Qt 开发后台服务避坑指南:从库存管理系统开发出现的问题来看后台开发常见问题与解决方案】
开发语言·qt·系统架构
froginwe1116 分钟前
Python3与MySQL的连接:使用mysql-connector
开发语言
Serene_Dream29 分钟前
JVM 并发 GC - 三色标记
jvm·面试
rannn_11133 分钟前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
灵感菇_35 分钟前
Java HashMap全面解析
java·开发语言
杜子不疼.36 分钟前
PyPTO:面向NPU的高效并行张量编程范式
开发语言