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 ★★★★
静态内部类 ★★★★★
枚举 ★★★★★(最安全)
相关推荐
陆小叁4 分钟前
基于Flink CDC实现联系人与标签数据实时同步至ES的实践
java·elasticsearch·flink
CHEN5_025 分钟前
【Java基础】反射,注解,异常,Java8新特性,object类-详细介绍
java·开发语言
Cx330❀18 分钟前
【数据结构初阶】--排序(四):归并排序
c语言·开发语言·数据结构·算法·排序算法
云间月131422 分钟前
飞算JavaAI智慧文旅场景实践:从景区管理到游客服务的全链路系统搭建
java·开发语言
盖世英雄酱5813623 分钟前
必须掌握的【InheritableThreadLocal】
java·后端
找不到、了28 分钟前
JVM的逃逸分析深入学习
java·jvm
杜子不疼.40 分钟前
《Python学习之使用标准库:从入门到实战》
开发语言·python·学习
用户03321266636742 分钟前
Java 查找并替换 PDF 中的文本:高效自动化处理指南
java
意疏44 分钟前
【C语言篇】srand函数的详细用法解析
c语言·开发语言
叽哥1 小时前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin