设计模式之单例模式解析

单例模式
1)动机

对于软件系统的某些类,无须创建多个实例,如 Windows 系统的任务管理器,重复对象会浪费系统资源。

2)概述
1.定义

确保某个类只有一个实例,而且自行实例化,并向整个系统提供这个实例,提供全局访问的方法。

在这里插入图片描述

2.角色

Singleton(单例)

在单例类的内部只生成一个实例,并提供一个静态的 getInstance() 工厂方法,让客户可以访问它的唯一实例;

为防止在外部对其实例化,将其构造函数设为私有;

在单例类内部定义了一个 Singleton 类型的静态对象,作为外部共享的唯一实例。

3)案例-简单单例模式

实现 Windows 任务管理器,类名为TaskManager,包含构造函数TaskManager(),显示进程的方法displayProcesses(),显示服务的方法displayServices();

class TaskManager
{
		 // 私有成员变量
     private static TaskManager tm = null;
     
     // 私有构造方法
     private TaskManager() {……} //初始化窗口
     
     // 成员方法
     public void  displayProcesses() {……} //显示进程
     public void  displayServices() {……} //显示服务
     
     // 工厂方法
     public static TaskManager getInstance()
     {
        if (tm == null)
        {
            tm = new TaskManager();
        }
        return tm;
    }
   ……
}
4)案例-饿汉式单例和懒汉式单例
1.饿汉式单例

定义静态变量时实例化单例类,当类被加载时,静态变量 instance 被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。

在这里插入图片描述

class EagerSingleton { 
    private static final EagerSingleton instance = new EagerSingleton(); 
    private EagerSingleton() { } 
 
    public static EagerSingleton getInstance() {
        return instance; 
    }   
}
2.懒汉式单例

第一次调用 getInstance() 时实例化,在类加载时并不自行实例化,为避免多个线程同时调用 getInstance(),使用 synchronized。

在这里插入图片描述

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

问题

在 getInstance() 增加关键字 synchronized,以处理多个线程同时访问的问题,但是每次调用 getInstance( ) 时都进行线程锁定判断,在多线程高并发环境中,会导致系统性能大大降低。

方案

减小锁范围+双重检查锁定(Double-Check Locking);

class LazySingleton { 
		// 原子性 volatile
    private volatile static LazySingleton instance = null; 
 
    private LazySingleton() { } 
 
    public static LazySingleton getInstance() { 
        //第一重判断
        if (instance == null) {
            //锁定代码块
            synchronized (LazySingleton.class) {
                //第二重判断
                if (instance == null) {
                    instance = new LazySingleton(); //创建单例实例
                }
            }
        }
        return instance; 
    }
}
3.饿汉式单例类与懒汉式单例类对比
分类类加载时机资源利用复杂度
饿汉式单例类类加载时
懒汉式单例类第一次使用时
5)案例-Initialization Demand Holder (IoDH) 实现单例类

在单例类中增加一个静态(static)内部类,在该内部类中创建单例对象,再将该单例对象通过 getInstance() 返回给外部使用。

class Singleton {
	private Singleton() {
	}
	
	private static class HolderClass {
       private final static Singleton instance = new Singleton();
	}
	
	public static Singleton getInstance() {
	    return HolderClass.instance;
	}
}

使用 IoDH,可以实现延迟加载,保证线程安全,不影响系统性能。

6)总结
1.优点

单例模式可以严格控制怎样以及何时访问。

在内存中只存在一个对象,可以节约系统资源,对于需要频繁创建和销毁的对象,单例模式可以提高系统性能。

允许可变数目的实例,使用与单例控制相似的方法来获得指定个数的对象实例。

2.缺点

因为单例模式中没有抽象层,所以单例类的扩展很困难;

单例类的职责过重;

如果实例化的共享对象长时间不被利用,会自动销毁并回收资源,下次利用时又将重新实例化,会导致共享的单例对象状态丢失。

3.适用场景

系统只需要一个实例对象,或者因资源消耗太大而只允许创建一个对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/477668.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue中循环数据,添加展开、收起操作

1.在data中定义变量 expandedIndex&#xff0c;默认展开第一条 expandedIndex:0,2.标题栏展开、收起显示判断&#xff0c;并填加点击事件 toggleVisibility <h5 class"titleLine">{{item.checkPart}} <span click"toggleVisibility(index)">…

【GPT概念04】仅解码器(only decode)模型的解码策略

一、说明 在我之前的博客中&#xff0c;我们研究了关于生成式预训练转换器的整个概述&#xff0c;以及一篇关于生成式预训练转换器&#xff08;GPT&#xff09;的博客——预训练、微调和不同的用例应用。现在让我们看看所有仅解码器模型的解码策略是什么。 二、解码策略 在之前…

【LVGL-按钮按钮矩阵部件】

LVGL-按钮&按钮矩阵部件 ■ LVGL-按钮部件■ 按钮部件&#xff1a; 点击三个按钮一个回调函数修改label值。 ■ LVGL-按钮矩阵部件■ 示例一&#xff1a;按钮换行&#xff0c;和宽度设置。■ 示例二&#xff1a;设置按钮宽度为2倍■ 示例三&#xff1a;获取点击的按钮下标&…

【以图搜图】GPUNPU适配万物识别模型和Milvus向量数据库

目录 以图搜图介绍项目地址Milvuscv_resnest101_general_recognition 代码使用流程结果展示模型部署环境Milvus部署及使用docker安装docker-compose安装Milvus可视化工具Attu进入网页端 Data数据示例点个赞再走呗&#xff01;比心&#x1f49e;️ 以图搜图 • &#x1f916; Mo…

【java】10.面向对象

一、类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 &#xff0c;所以我们也常常说万物皆对象。 * 类 * 类的理解 * 类是对现实生活中一类具有共同属性和行为的事物的抽象 * 类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合 * 简单理解&am…

C#、.NET版本、Visual Studio版本对应关系及Visual Studio老版本离线包下载地址

0、写这篇文章的目的 由于电脑的环境不同&#xff0c;对于一个老电脑找到一个适配的vscode环境十分不易。总结一下C#、.NET、Visual Studio版本的对应关系&#xff0c;及各个版本Visual Studio的下载地址供大家参考 1、C#、.NET版本、Visual Studio版本对应关系如下 2、Visua…

使用paddleocr

paddle快速开始 具体安装流程 安装shapely库报错怎么办&#xff1f; 选定下载paddleocr2.2时报错 原因是因为python版本不支持&#xff1a; 之后重新创建新的环境&#xff0c;安装python3.8再来一遍 【重新选取对应whl文件&#xff0c;确认文件名是否可用】 之后是可以了…

ARM Coresight 系列文章 11.1 -- CoreSight Cortex-M33 CTI 详细介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 CTI 的工作原理CTI 主要特点CTI的使用场景CTI 的工作原理 CTI 允许不同的调试和追踪组件之间基于特定事件进行交互。例如,当一个断点被命中时,CTI 可以用来触发内存的追踪捕捉或者外部仪器的行为,反之亦然。这种…

C#多态性

文章目录 C#多态性静态多态性函数重载函数重载 动态多态性运行结果 C#多态性 静态多态性 在编译时&#xff0c;函数和对象的连接机制被称为早期绑定&#xff0c;也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为&#xff1a; 函数重载 运算符重载 运算符重载将…

iPhone语音备忘录误删?掌握这几个技巧轻松恢复【详】

语音备忘录是一款强大的应用程序&#xff0c;它允许用户使用语音输入功能来快速记录想法、提醒、待办事项等。无论是在行进间、工作中还是日常生活中&#xff0c;语音备忘录都是一个非常实用的工具&#xff0c;可以帮助您随时随地记录重要信息&#xff0c;而无需打字或者手动输…

什么是Vector Database?

此为看完视频What is a Vector Database?后的笔记。 作者首先对数据库做了分类&#xff0c;其中RTweb表示real time web app。 然后对用例做了分类&#xff0c;最后一个就是适合于AI的近似搜索。 好处&#xff0c;包括灵活性&#xff0c;可扩展性和性价比。 本视频最重要的…

数据清洗(一)Excel

一、引言 线上出现问题之后的数据清洗是少不了的&#xff0c;有的可以直接通过接口或者mq补偿&#xff0c;有的写sql更新db就可以&#xff0c;但是在匹配关系比较复杂的时候就需要建立临时表做关联匹配&#xff0c;数据量不大可以直接用excel进行匹配。 二、Excel清洗数据 作者…

Windows系统服务器宝塔面板打开提示Internal Server Error错误

1、cmd运行bt命令 2、尝试输入16修复程序 3、如果不行&#xff0c;输入17升级程序

你知道弧幕影院如何制作吗?其应用领域竟如此广泛!

“沉浸式”作为如今备受热议的内容展示形式&#xff0c;其有着多种可实现的途径&#xff0c;其中弧幕影院作为一项有着独特视觉效果、沉浸式观影体验的技术类型&#xff0c;便是大多数影院、主题公园等娱乐场景的必备设计展项&#xff0c;这种弧幕影院通常使用大型的半圆形屏幕…

PyQt:实现菜单栏的点击拖动效果

一、整体步骤 1.设计UI文件 2.调用显示 3.效果展示 二、设计UI文件 1.添加 Scroll Area控件&#xff0c;作为菜单栏的布置区域 2.设置 Scroll Area控件的属性 3.Scroll Area控件内放置 按钮控件 组成菜单栏 此处&#xff0c;放置了需要了6个按钮&#xff0c;并设置按钮的固…

YoloV8改进策略:BackBone改进|PKINet

摘要 PKINet是面向遥感旋转框的主干,网络包含了CAA、PKI等模块,给我们改进卷积结构的模型带来了很多启发。本文,使用PKINet替代YoloV8的主干网络,实现涨点。PKINet是我在作者的模型基础上,重新修改了底层的模块,方便大家轻松移植到YoloV8上。 论文:《Poly Kernel Ince…

科学认识并正确运用人工智能技术赋能国际传播

以下文章来源&#xff1a;学习时报 加强国际传播能力建设&#xff0c;全面提升国际传播效能&#xff0c;形成同我国综合国力和国际地位相匹配的话语权&#xff0c;已成为实现中国式现代化需要解决好的一个重大问题。文生视频模型Sora&#xff0c;是继ChatGPT之后又一推动传播智…

SinoDB系统数据库

在SinoDB数据库的一个实例中&#xff0c;存在多个数据库&#xff0c;分为系统数据库和用户数据库。系统数据库在实例初始化时自动创建&#xff0c;存放实例级别上的监控信息、数据字典信息&#xff0c;用户能够访问而不能修改这些数据。用户数据库由用户根据需要创建&#xff0…

MyBatis3源码深度解析(十九)MyBatis日志实现

文章目录 前言第七章 MyBatis日志实现7.1 Java日志体系7.1.1 常用日志框架7.1.2 Java日志发展史7.1.3 日志接口与日志实现的绑定 7.2 MyBatis日志实现7.2.1 Log接口7.2.2 LogFactory工厂7.2.3 MyBatis日志自动查找7.2.4 MyBatis日志类型配置 7.3 小结 前言 日志是Java应用中必…

信驰达车规蓝牙模块RF-BM-2642QB1I赋能汽车T-Box

近年来&#xff0c;随着人们对数据传输需求的增长&#xff0c;传统网络布线的通讯方式逐渐显现出满足不了的局限性&#xff0c;与此同时&#xff0c;各种无线传输技术迅速发展。汽车工业同样需要无线通讯技术&#xff0c;但红外技术、802.11、HomeRF等技术在汽车工业中存在一定…