编程-设计模式 3:单例模式

设计模式 3:单例模式

定义与目的
  • 定义:单例模式确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
  • 目的:这种模式通常用于那些需要频繁访问且只需一个实例的对象,例如配置管理器、日志记录器等。
实现示例

单例模式的一个简单实现是使用懒加载方式,确保在第一次调用时才创建实例。这里展示一个线程安全的懒加载实现:

java 复制代码
public class Singleton {

    // 使用 volatile 关键字确保多线程环境下的正确可见性
    // volatile 关键字保证了对 instance 变量的修改对所有线程可见,
    // 并且禁止了编译器和处理器对 instance 的读写进行优化(如重排序)
    private static volatile Singleton instance;

    // 构造器私有化,防止外部实例化
    // 这样可以确保除了 Singleton 类自身之外的其他类无法直接创建 Singleton 的实例
    private Singleton() {}

    // 提供一个静态方法来获取 Singleton 的唯一实例
    public static Singleton getInstance() {
        // 第一次检查:如果 instance 已经被初始化,则直接返回该实例
        // 这样可以避免不必要的同步开销
        if (instance == null) {
            // 使用 synchronized 关键字来保证线程安全
            // 同步块限制在最小范围,以提高性能
            synchronized (Singleton.class) {
                // 第二次检查:确保在多线程环境下只会创建一个实例
                // 这里即使有多个线程同时进入同步块,也只会有一个线程创建实例
                if (instance == null) {
                    // 创建 Singleton 的唯一实例
                    instance = new Singleton();
                }
            }
        }
        // 返回 Singleton 的唯一实例
        return instance;
    }

    // 示例方法
    public void doSomething() {
        System.out.println("Singleton doing something...");
    }

    // 测试方法
    public static void main(String[] args) {
        // 获取 Singleton 的实例并调用 doSomething 方法
        Singleton singleton = Singleton.getInstance();
        singleton.doSomething();  // 输出: Singleton doing something...
    }
}
使用场景
  • 当你需要在整个应用程序中共享资源,并且希望确保该资源只能被创建一次时。
  • 当你需要一个全局的配置管理器时。
  • 当你需要一个全局的日志记录器时。
  • 当你需要一个全局的状态管理器时。

单例模式是一种常用的模式,它可以简化对全局资源的管理,并确保这些资源不会被滥用。然而,在多线程环境中实现单例模式时,必须注意线程安全问题。上面的示例使用了双重检查锁定(Double-Checked Locking)来确保线程安全性。

小结

  • 创建型模式的共性:这些模式都关注于对象的创建过程,使得程序能够更加灵活地处理对象创建的逻辑。
  • 何时使用这些模式:当你希望将对象的创建逻辑与使用逻辑分离时,或者需要在运行时动态创建对象时。

单例模式是创建型模式中最简单的一种,它确保了整个系统中只有一个实例存在,并提供了一个全局访问点。这种模式在实际应用中非常普遍,尤其是在需要全局唯一实例的情况下。

相关推荐
开开心心就好2 分钟前
本地文件搜索工具,双击Ctrl就能呼出搜索
java·服务器·前端·支持向量机·ffmpeg·音视频·模拟退火算法
独隅7 分钟前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
ByteCoder.14 分钟前
班前十分钟的清单,按体检引导单来写
java·服务器·前端·助播虾
海的透彻16 分钟前
如何让docker容器启动时用自定义的用户
java·docker·dubbo
疯狂学习GIS21 分钟前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
GG.WinGel32 分钟前
质数数目(蓝桥杯练习题)
java·数据结构·算法·青少年编程·蓝桥杯
泡泡糖的中文规格书37 分钟前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui40 分钟前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu
秋天的怀念_David1 小时前
算法一千零一夜 · 第十七夜 长街点灯
java·程序人生·算法
不吃鱼的羊1 小时前
如何应对恐惧
java