当前位置: 首页 > news >正文

【设计者模式】单例模式

文章目录

  • 1、模式定义
  • 2、代码实现
    • (1)双重判空加锁方式
      • 两次判空的作用?
      • volatile 关键字的作用?
      • 构造函数私有?
    • (2)静态内部类【推荐】
    • (3)Kotlin中的单例模式
      • lateinit 和 by lazy 的区别:
  • 3、优缺点
  • 4、参考资料

1、模式定义

  • 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
  • 单例特别:(1)单例模式只能有一个实例。(2)单例类必须创建自己的唯一实例。(3)单例类必须向其他对象提供这一实例。

2、代码实现

(1)双重判空加锁方式

public class Singlnton{private static volatile Singlnton instance;private Singlnton(){}public static Singlnton getInstance(){ // 1if(instance==null){ // 2synchronized(Singlnton.class){ // 3if(instance==null){ // 4instance = new Singlnton(); // 5}}}return instance;}}

两次判空的作用?

  • 第一次:避免加锁
  • 第二次:进行实例化

volatile 关键字的作用?

  • 双重检锁单例模式在 CPU 的工作流,主要分为三步,1:分配内存对象空间。2:初始化对象。3:设置 instance 执行刚才分配的内存地址。注意 JVM 和 CPU 优化会指令重排,上面顺序会变成 1 -> 3 -> 2,单线程环境下,此顺序是没有问题,2 和 3 前后没有依赖性,但是在多线程情况下会有这种情况,当线程 A 在执行第 5 行代码时,B 线程进来执行到第 2 行代码。假设此时 A 执行的过程中发生了指令重排序,即先执行了 1 和 3,没有执行 2。那么由于 A 线程执行了 3 导致 instance 指向了一段地址,所以 B 线程判断 instance 不为 null,会直接跳到第 6 行并返回一个未初始化的对象,此时会产生空指针异常。volatile 能保持指令的有序性,能够有效禁止指令重排序。
  • 注意:“Singlnton instance” 相当于分配内存对象空间;“new Singlnton()” 相当于初始化对象;"="相当于设置 instance 执行刚才分配的内存地址。

构造函数私有?

  • 无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法 getInstance 来得到该类的唯一实例

(2)静态内部类【推荐】

public class Singlnton{private Singlnton(){}private static class SinglntonHolder{private static Singlnton INSTANCE = new Singlnton();}public static Singlnton getInstance(){return SinglntonHolder.INSTANCE;}}
  • 利用 JAVA 虚拟机加载类的特性实现延迟加载和线程安全
  • 由于静态单例对象没有作为 Singleton 的成员变量直接实例化,因此类加载时不会实例化 Singleton,第一次调用 getInstance() 时将加载内部类 SingletonHolder,在该内部类中定义了一个 static 类型的变量 INSTANCE,此时会首先初始化这个成员变量,由 Java 虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。由于 getInstance() 方法没有任何线程锁定,因此其性能不会造成任何影响。
  • 类加载机制

(3)Kotlin中的单例模式

class Singlnton private constructor(){companion object{val instance : Singlnton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {Singlnton() }}}class Singlnton private constructor(){companion object{@Volatileprivate var instance: Singlnton? = nullfun getInstance(): Singlnton =instance ?: synchronized(this) {instance ?: Singlnton().also {instance = it}}}}

lateinit 和 by lazy 的区别:

  • lateinit 只能用于修饰变量 var,不能用于可空的属性和 Java 的基本类型。
  • lateinit 可以在任何位置初始化并且可以初始化多次。
  • lazy() 只能用于修饰常量 val,并且 lazy() 是线程安全的。
  • lazy() 是一个函数,可以接受一个 Lambda 表达式作为参数,第一次调用时会执行 Lambda 表达式,以后调用该属性会返回之前的结果。
  • lazy() 源码分析

3、优缺点

  • 优点:
    • (1)在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
    • (2)避免对资源的多重占用。
  • 缺点:
    • (1)没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
    • (2)滥用单例会带来一些负面问题。如果实例化的对象长时间不被使用,系统会认定为垃圾而回收,这将导致共享对象状态的改变
  • 注意事项:++不能使用反射调用私有构造器,这样会实例化一个新的对象++
  • 如何避免反射创建新的单例对象

4、参考资料

  • 单例模式 Android 校招面试指南(只能在手机端打开)

相关文章:

【设计者模式】单例模式

文章目录 1、模式定义2、代码实现(1)双重判空加锁方式两次判空的作用?volatile 关键字的作用?构造函数私有? (2)静态内部类【推荐】(3)Kotlin中的单例模式lateinit 和 by…...

Windows7缺失api-ms-win-crt-runtime-l1-1-0.dll的解决方法

api-ms-win-crt-runtime-l1-1-0.dll是一个在Windows操作系统环境下至关重要的动态链接库文件(DLL),它是Microsoft Visual C Redistributable的一部分,负责实现C运行时库的相关功能。这个特定的DLL文件提供了大量的底层运行支持&am…...

coqui-ai/TTS 安装使用

Coqui AI的TTS是一款开源深度学习文本转语音工具,以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库,能够轻松集成到各种应用中,并允许用户通过简单API进行个性化声音训练与微调。其技术亮点包括但不限于低资源适应性&#xff0…...

Spring AOP相关注解及执行顺序

Aspect(切面):用于标识一个类是切面的注解。通常与其他通知注解一起使用,定义切面类。 Pointcut(切点): 注解来定义切点,它用于描述哪些连接点将会被通知所通知。 连接点&#xff…...

C++从零开始的打怪升级之路(day44)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料 那么开启正题 今天分享的是关于二叉搜索树的知识点 1.二叉搜索树概念 二叉搜…...

[C++核心编程](七):类和对象——运算符重载*

目录 四则运算符重载 左移运算符重载 递增运算符重载 赋值运算符重载 关系运算符重载 函数调用运算符重载 对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 四则运算符重载 对自定义数据类型实现四则运算(加减乘除&…...

什么是MVC和MVVM

**MVC和MVVM是两种流行的软件架构模式,它们在前端开发中被广泛采用来组织代码和管理应用程序的复杂性**。具体如下: MVC(Model-View-Controller): 1. 模型(Model):负责管理数据和业…...

物体检测-系列教程23:YOLOV5 源码解析13 (SPP层、Flatten模块、Concat模块、Classify模块)

😎😎😎物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 17、SPP模块 17.1 SPP类 SPP是一种特殊的池化策略,最初在YOLOv3-SPP中被使用…...

2024.3.6每日一题

LeetCode 找出数组中的 K -or 值 题目链接:2917. 找出数组中的 K-or 值 - 力扣(LeetCode) 题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有在 nums 中&…...

YOLOSHOW - YOLOv5 / YOLOv7 / YOLOv8 / YOLOv9 基于 Pyside6 的图形化界面

YOLOSHOW 是一个基于 PySide6(Qt for Python)开发的图形化界面应用程序,主要用于集成和可视化YOLO系列(包括但不限于YOLOv5、YOLOv7、YOLOv8、YOLOv9)的目标检测模型。YOLOSHOW 提供了一个用户友好的交互界面&#xff…...

sql高级

sql高级 SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目。 SELECT TOP 子句对于拥有数千条记录的大型表来说,是非常有用的。 **注意:**并非所有的数据库系统都支持 SELECT TOP 语句。 MySQL 支持 LIMIT 语句来选取指定的条数数据, O…...

更快更强,Claude 3全面超越GPT4,能归纳15万单词

ChatGPT4和Gemini Ultra被Claude 3 AI模型超越了? 3月4日周一,人工智能公司Anthropic推出了Claude 3系列AI模型和新型聊天机器人,其中包括Opus、Sonnet和Haiku三种模型,该公司声称,这是迄今为止它们开发的最快速、最强…...

devc++小游戏3.8.5

导航: Dev-c跑酷小游戏 1.0.0 devc跑酷小游戏1.2.5 devc跑酷游戏1.2.6 devc跑酷游戏2.0.0 devc跑酷游戏2.0.1 devc跑酷游戏2.4.0 devc跑酷小游戏3.5.0 更新内容 重磅回归,存档搞定!!! 每一关需要前一关已…...

Java网络通信TCP

目录 TCP两个核心类 服务端 1.用ServerSocker类创建对象并且手动指定端口号 2.accept阻塞连接服务端与客户端 3.给客户端提供处理业务方法 4.处理业务 整体代码 客户端 1.创建Socket对象,并连接服务端的ip与端口号 2.获取Socket流对象,写入数据…...

层级锁笔记

注意看test_hierarchy_lock函数&#xff1a;如果thread t2的不注释&#xff0c;就会报错。 这是因为层级锁 更强调单个线程内上锁的顺序。 线程t2已经获取了hmtx2&#xff0c;再试图获取hmtx1就会因为违反层级顺序而抛出异常。 #include <mutex> #include <thread&g…...

基于SpringBoot+Vue 的专家医院预约挂号系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

计算机基础专升本笔记十二-Excel常用快捷键大全

计算机基础专升本笔记十二-Excel常用快捷键大全 Excel常用快捷键 按键作用Ctrl 0隐藏列Ctrl 1设置单元格格式Ctrl 2添加或取消字体加粗Ctrl 3添加或取消字体倾斜Ctrl 4添加或取消下划线Ctrl 5添加或取消删除线Ctrl 6隐藏或显示图形Ctrl 7隐藏工具栏Ctrl 8隐藏或显示…...

制作耳机壳的UV树脂和塑料材质相比优势有哪些?

制作耳机壳的UV树脂相比塑料材质有以下优势&#xff1a; 高强度与耐磨性&#xff1a;UV树脂具有高强度和耐磨性&#xff0c;能够更好地保护耳机内部零件&#xff0c;延长耳机使用寿命。相比之下&#xff0c;塑料材质可能较易磨损或刮伤。耐高温&#xff1a;UV树脂具有较好的耐…...

JS(JavaScript)中如何实现,复选框checkbox多选功能

起始界面&#xff1a; 代码元素&#xff1a; <p><input type"checkbox" id"checkedAll"> 全选按钮</p><p><input type"checkbox" class"cl"> 选项1</p><p><input type"checkbox&qu…...

直接修改zynq petalinux编译出来的rootfs.cpio.gz文件内容

xilinx zynq petalinux 默认编译打包出的SPI flash烧写启动文件是BOOT.BIN&#xff0c;然而每次需要修改rootfs内的文件时都要重新build rootfs 然后再 package一次才能生成新的BOOT.bin文件&#xff0c;地球人都知道petalinux编译一次是很耗时间的&#xff0c;那么有没有什么简…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...