• 设计模式—单例模式


    单例模式(创建型设计模式)

    分为 :饿汉式单例模式、懒汉式单例模式、线程安全的懒汉式单例模式;

    标准回答 :

    • 含义:一个类仅有一个实例化对象,其最大特点是构造函数私有化;
    • 特点:构造函数私有化,从而避免外界直接使用构造函数直接实例化该类的对象。
    • 单例模式主要分为饿汉式,懒汉式,线程安全的懒汉式。
      • 饿汉式在类加载是就创建了实例对象,但是这样有可能造成资源的浪费;
      • 懒汉式,在类第一次被调用时创建实例,这样可能会造成线程安全问题;
      • 线程安全的懒汉式,则是在懒汉式的基础上加锁

    一、单例模式要做的

    • 1、单例类只能有一个实例。
    • 2、单例类必须自己创建自己的唯一实例。(构造函数私有化)
    • 3、单例类必须给所有其他对象提供这一实例。(通过公有的getInstance方法,提供一个全局访问点)

    二、单例模式主要解决的问题:

    主要解决:一个全局使用的类频繁地创建与销毁。

    何时使用:当您想控制实例数目,节省系统资源的时候。

    三、单例模式使用场景:

    • 1、要求生产唯一序列号。
    • 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
    • 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

    1.饿汉式单例模式: 在类加载时就会初始化静态变量实例,这时候类的私有构造函数就会被调用,创建唯一的实例。

    # 是否多线程安全:是;它基于 classloader 机制避免了多线程的同步问题
    # 其他描述:
    	这种方式比较常用,但容易产生垃圾对象。
    - 优点:没有加锁,执行效率会提高。
    - 缺点:类加载时就初始化,浪费内存。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Singleton{
        //在类加载时就会初始化静态变量实例
    	private static Singleton instance = new Singleton(); 
    	// 构造方法私有,确保外界不能直接实例化
        private Singleton(){} 
        //通过公有的静态方法获取实例对象
        public static Singleton getInstance(){ 
            return instance; 
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.懒汉式单例模式: 类在加载时不会初始化静态变量instance,而是在第一次被调用时将自己初始化。

    # 是否多线程安全:否;因为没有加锁 synchronized
    # 其他描述:
    	这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程,不要求线程安全,在多线程不能正常工作。
    
    • 1
    • 2
    • 3
    public class Singleton { 
        //先置空,在调用的时候实例化对象
        private static Singleton instance = null; 
        // 私有构造方法,确保外界不能直接实例化。
        private Singleton() {} 
        // 通过公有的静态方法获取对象实例 
        public static Singleton getInstace() {
            if (instance == null) { 
                instance = new Singleton(); } 
            return instance; 
        } 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    问题:

    如果线程A和B同时调用此方法,会出现执行if (instance == null)语句时都为真的情况,那么线程A和B都会创建一个对象,那内存中就会出现两个对象,这违反了单例模式的定义。

    如何解决:线程安全的懒汉式

    为解决这一问题,使用synchronized关键字对静态方法 getInstance()进行同步,防止多线程同时进入造成 instance 被多次实例化。

    3.线程安全的的懒汉式单例模式

    # 是否多线程安全:是;因有加锁 synchronized
    # 其他描述:
    这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
    	优点:第一次调用才初始化,避免内存浪费。
    	缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
    getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Singleton { 
        private static Singleton instance = null; 
        // 私有构造方法,确保外界不能直接实例化。 
        private Singleton() {} 
        // 通过公有的静态方法获取对象实例 
        synchronized public static Singleton getInstace() { 
            if (instance == null) { 
                instance = new Singleton(); 
            } 
            return instance; 
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.饿汉式和懒汉式的对比:

    饿汉式单例类在资源利用效率上不如懒汉式单例类,但从速度和反应时间来看,饿汉式单例类要优于懒汉式单例类。

    资源利用效率:饿汉式<懒汉式;

    速度和反应上:饿汉式>懒汉式;

    5.单例模式优缺点:

    单例模式的优点:在一个对象需要频繁的销毁、创建;而销毁、创建性能又无法优化时,单例模式的优势尤其明显 ;

    • 在内存里只有一个实例,减少了内存的开销;尤其是频繁的创建和销毁实例
    • 在一个对象的产生需要比较多资源时,如读取配置、产生其他依赖对象时,则可以通过在启用时直接产生一个单例对象,然后用永久驻留内存的方式来解决;
    • 单例模式可以避免对资源的多重占用;因为只有一个实例,避免了对一个共享资源的并发操作;
    • 单例模式可以在系统设置全局的访问点,优化和共享资源访问;

    单例模式的缺点:

    • 单例模式没有接口,不能继承;无法创建子类,扩展困难;若要扩展,除了修改代码基本上没有第二种途径可以实现;
    • 单例模式对测试不利;在并行开发环境中,如果采用单例模式的类没有完成,是不能进行测试的;
    • 单例模式与单一职责原则有冲突;一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要用单例模式取决于环境
  • 相关阅读:
    含文档+PPT+源码等]精品基于SSM的社团管理系统[包运行成功]程序设计源码计算机毕设
    数学建模:最优化问题及其求解概述
    DDIO和DMA有什么区别
    基于JavaSwing开发网络QQ聊天程序(Socket Mysql数据库) 大作业 毕业设计项目源码
    大二学生JavaScript实训大作业——动漫秦时明月7页 期末网页制作 HTML+CSS+JavaScript 网页设计实例 企业网站制作
    Magnet: Push-based Shuffle Service for Large-scale Data Processing
    【Java面试】来讲一讲你对String的理解
    DOM中的node节点属性详解
    【Python】python中多进程处理
    react 使用useRoutes遇到的问题
  • 原文地址:https://blog.csdn.net/m0_48904153/article/details/126142396