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) 实现最简单,线程安全,防止反序列化创建新实例 枚举类型不灵活,无法进行细粒度控制

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

相关推荐
坊钰26 分钟前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang131 分钟前
leetcode hot100 LRU缓存
java·开发语言
会说法语的猪36 分钟前
springboot实现图片上传、下载功能
java·spring boot·后端
码农老起37 分钟前
IntelliJ IDEA 基本使用教程及Spring Boot项目搭建实战
java·ide·intellij-idea
m0_7482398341 分钟前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
麒麟而非淇淋1 小时前
Day13 苍穹外卖项目 工作台功能实现、Apache POI、导出数据到Excel表格
java
越甲八千1 小时前
重温设计模式--代理、中介者、适配器模式的异同
设计模式·适配器模式
小爬虫程序猿1 小时前
利用Java爬虫获取速卖通(AliExpress)商品详情的详细指南
java·开发语言·爬虫