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 ★★★★
静态内部类 ★★★★★
枚举 ★★★★★(最安全)
相关推荐
IT观测1 分钟前
深度分析俩款主流移动统计工具Appvue和openinstall
android·java·数据库
Oueii2 分钟前
嵌入式LinuxC++开发
开发语言·c++·算法
华科易迅2 分钟前
Spring AOP(注解前置+后置通知)
java·后端·spring
sw1213893 分钟前
嵌入式C++驱动开发
开发语言·c++·算法
2501_924952694 分钟前
C++中的适配器模式
开发语言·c++·算法
2301_776508725 分钟前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
堕2747 分钟前
JavaEE初阶——《计算机是如何工作的》
java·java-ee
良木生香9 分钟前
【C++初阶】:C++类和对象(中):类的默认成员函数---万字解说(最主要的四点)
c语言·开发语言·c++
2501_945424809 分钟前
实战:用Python开发一个简单的区块链
jvm·数据库·python
☆56611 分钟前
C++安全编程指南
开发语言·c++·算法