java设计模式:02-01-单例模式

单例模式(Singleton Pattern)

单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通常用于需要全局唯一实例的场景,例如:

  • 日志记录(Logging):应用程序中的所有组件都需要记录日志,单例模式可以确保日志记录器的唯一实例。
  • 配置管理(Configuration Management):配置文件的读取和写入需要全局唯一实例,以避免不同组件之间的配置不一致。
  • 连接池(Connection Pooling):数据库连接池需要管理有限数量的连接实例,单例模式可以确保连接池的唯一实例。
  • 缓存(Caching):全局缓存需要唯一实例,以便于所有组件共享缓存数据。
  • 线程池(Thread Pool):线程池需要全局唯一实例,以确保系统中只有一个线程池在管理线程。

单例模式的多种实现方式

1. 饿汉式(Eager Initialization)

思想:在类加载时就创建单例实例,避免了多线程问题,但如果实例占用资源较大且不一定会用到,会造成资源浪费。

实现方式

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

    private SingletonEager() {
        // 防止实例化的私有构造函数
    }

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

优点

  • 实现简单。
  • 类加载时创建实例,线程安全。

缺点

  • 如果单例实例占用资源较大且未使用,会造成资源浪费。
2. 懒汉式(Lazy Initialization)

思想:在第一次需要实例时创建,避免资源浪费,但需要处理多线程问题。

实现方式

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

    private SingletonLazy() {
        // 防止实例化的私有构造函数
    }

    public static synchronized SingletonLazy getInstance() {
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
}

优点

  • 实例在第一次使用时创建,节省资源。

缺点

  • 需要加锁以确保线程安全,性能开销较大。
3. 双重检查锁定(Double-Checked Locking)

思想:结合饿汉式和懒汉式的优点,第一次检查实例是否为 null,避免不必要的同步,提高性能。

实现方式

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

    private SingletonDCL() {
        // 防止实例化的私有构造函数
    }

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

优点

  • 提高了懒汉式的性能,减少同步开销。

缺点

  • 代码较为复杂。
4. 静态内部类(Bill Pugh Singleton)

思想:利用类加载机制,只有在使用时才加载内部类,从而实现延迟加载和线程安全。

实现方式

java 复制代码
public class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {
        // 防止实例化的私有构造函数
    }

    private static class SingletonHelper {
        private static final SingletonStaticInnerClass INSTANCE = new SingletonStaticInnerClass();
    }

    public static SingletonStaticInnerClass getInstance() {
        return SingletonHelper.INSTANCE;
    }
}

优点

  • 实现简单。
  • 线程安全。
  • 延迟加载。

缺点

  • 无法进行细粒度控制。
5. 枚举单例(Enum Singleton)

思想:使用 Java 枚举类型的特性,枚举类的实例天生是单例。

实现方式

java 复制代码
public enum SingletonEnum {
    INSTANCE;

    public void someMethod() {
        // some method
    }
}

优点

  • 实现最简单。
  • 线程安全。
  • 防止反序列化创建新实例。

缺点

  • 枚举类型不灵活,无法进行细粒度控制。

总结

实现方式 优点 缺点
饿汉式(Eager Initialization) 实现简单,线程安全 可能造成资源浪费
懒汉式(Lazy Initialization) 实例在第一次使用时创建,节省资源 需要加锁以确保线程安全,性能开销较大
双重检查锁定(Double-Checked Locking) 提高了懒汉式的性能,减少同步开销 代码较为复杂
静态内部类(Bill Pugh Singleton) 实现简单,线程安全,延迟加载 无法进行细粒度控制
枚举单例(Enum Singleton) 实现最简单,线程安全,防止反序列化创建新实例 枚举类型不灵活,无法进行细粒度控制

不同的实现方式各有优劣,选择哪种实现方式应根据具体的应用场景和需求来决定。如果需要简单而且线程安全的实现,枚举单例是一个很好的选择。如果需要延迟加载且线程安全,静态内部类和双重检查锁定都是不错的选择。

相关推荐
小蒜学长1 分钟前
springboot多功能智能手机阅读APP设计与实现(代码+数据库+LW)
java·spring boot·后端·智能手机
charlie11451419137 分钟前
精读 C++20 设计模式:行为型设计模式 — 访问者模式
c++·学习·设计模式·访问者模式·c++20
蓝莓味的口香糖2 小时前
【JS】什么是单例模式
开发语言·javascript·单例模式
zizisuo3 小时前
解决在使用Lombok时maven install 找不到符号的问题
java·数据库·maven
笨蛋少年派3 小时前
JAVA基础语法
java·开发语言
Haooog3 小时前
654.最大二叉树(二叉树算法)
java·数据结构·算法·leetcode·二叉树
我真的是大笨蛋3 小时前
依赖倒置原则(DIP)
java·设计模式·性能优化·依赖倒置原则·设计规范
东方芷兰4 小时前
JavaWeb 课堂笔记 —— 20 SpringBootWeb案例 配置文件
java·开发语言·笔记·算法·log4j·intellij-idea·lua
Roye_ack4 小时前
【项目实战 Day9】springboot + vue 苍穹外卖系统(用户端订单模块 + 商家端订单管理模块 完结)
java·vue.js·spring boot·后端·mybatis
人间有清欢4 小时前
java数据权限过滤
java·mybatis·权限控制·数据过滤