• 小谈设计模式(22)—单例模式


    专栏介绍

    专栏地址

    link

    专栏介绍

    主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
    在这里插入图片描述

    单例模式

    单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点。单例模式在许多情况下都非常有用,比如控制资源的访问、线程池、日志对象等。
    在这里插入图片描述

    点睛所在

    控制对象的实例化过程。通常情况下,我们可以通过将构造函数私有化来防止外部直接创建对象。然后,我们需要提供一个静态方法来获取单例对象,这个方法负责创建对象并在后续调用时返回同一个实例。

    优缺点分析

    优点

    确保只有一个实例

    单例模式可以确保一个类只有一个实例存在,这样可以避免多个实例之间的冲突和资源的浪费。

    全局访问点

    单例模式提供了一个全局访问点,使得其他对象可以方便地访问该实例,避免了对象之间的耦合。

    节省资源

    由于单例模式只创建一个实例,可以节省系统资源,特别是在需要频繁创建和销毁对象的情况下,可以显著提高系统的性能。

    线程安全

    通过合理的实现方式,单例模式可以保证在多线程环境下的线程安全性。

    在这里插入图片描述

    缺点

    难以扩展

    由于单例模式只允许存在一个实例,因此难以扩展为多个实例。如果需要创建多个实例,就需要修改单例模式的实现。

    对象的生命周期

    由于单例模式的实例在整个程序运行期间都存在,可能会导致对象的生命周期过长,造成资源的浪费。

    单一职责原则

    单例模式将创建对象和控制访问对象的责任集中在一起,违反了单一职责原则。这可能会导致单例类的职责过重,不利于代码的维护和扩展。

    隐藏依赖关系

    单例模式可能会导致对象之间的依赖关系变得隐式,使得代码的可读性和可维护性降低。
    在这里插入图片描述

    Java程序实例

    实例a

    public class Singleton {
        private static Singleton instance;
    
        private Singleton() {
            // 私有构造函数
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    分析

    在这个实现中,我们将构造函数私有化,然后提供了一个静态方法 getInstance() 来获取单例对象。在这个方法中,我们首先检查实例是否已经被创建,如果没有则创建一个新的实例并返回。这种实现方式被称为 “懒汉式”,因为它只有在第一次调用 getInstance() 方法时才会创建实例。

    但是,这种实现方式并不是线程安全的。如果多个线程同时调用 getInstance() 方法,可能会导致多个实例被创建。为了解决这个问题,我们可以使用同步锁来保证线程安全。

    实例b,更安全

    public class Singleton {
        private static Singleton instance;
    
        private Singleton() {
            // 私有构造函数
        }
    
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    分析

    在这个实现中,我们使用了 synchronized 关键字来保证线程安全。但是,这种实现方式会导致性能问题,因为每次调用 getInstance() 方法时都会进行同步。
    在这里插入图片描述

    优化 ——“双重检查锁定” 实现方式

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    分析

    在这个实现中,我们首先检查实例是否已经被创建,如果没有则进入同步块。在同步块中,我们再次检查实例是否已经被创建,如果没有则创建一个新的实例。使用 volatile 关键字可以保证多线程下的可见性。
    在这里插入图片描述

    总结

    单例模式在一些特定的场景下非常有用,可以确保一个类只有一个实例,并提供全局访问点。但是,需要注意单例模式的实现方式,避免出现线程安全和性能问题,并权衡其优缺点来决定是否使用单例模式。

  • 相关阅读:
    服务医学,基于目标检测模型实现细胞检测识别
    剑指 Offer II 021. 删除链表的倒数第 n 个结点【链表】
    SDK日志上传性能优化
    Vue开发中的一些常见套路和技巧(上)
    k8s named Kubernetes
    【kubernetes】k8s对象☞pod
    wrf--运行real.exe时报错:“Could not find level above ground“ error
    RHCE8 资料整理(三)
    webpack实践:解决组件库的静态资源在项目上加载不了的问题!
    Day 02 python学习笔记
  • 原文地址:https://blog.csdn.net/weixin_74888502/article/details/133642307