【Java】单例模式
单例模式是面试中常考的设计模式之一
在面试中,面试官常常会要求写出两种类型的单例模式并解释原理
本文中,将从0到1的介绍单例模式究竟是什么
文章目录
- ✍一、什么是设计模式?
- ✍二、单例模式是什么?
- ✍三、单例模式的类型
- **1.饿汉式**
- 2.懒汉式
- 3.优化懒汉式
- 4.指令重排
- 5.完整代码
✍一、什么是设计模式?
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。简单说:
模式:在某些场景下,针对某类问题的某种通用的解决方案。
场景:项目所在的环境
问题:约束条件,项目目标等
解决方案:通用、可复用的设计,解决约束达到目标。
用生活中的事务来介绍:
设计模式好⽐象棋中的 “棋谱”. 红⽅当头炮, ⿊⽅⻢来跳. 针对红⽅的⼀些⾛法, ⿊⽅应招的时候有⼀些固定的套路. 按照套路来⾛局势就不会吃亏.
✍二、单例模式是什么?
单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
简单概括:
- 单例模式能保证某个类在程序中只存在唯⼀⼀份实例,而不会创建出多个实例.
✍三、单例模式的类型
单例模式具体的实现⽅式有很多. 最常⻅的是 “饿汉” 和 “懒汉” 两种.
- 饿汉式:在类加载过程中就创建了实例。
- 懒汉式:在真正需要使用时,才会创建实例。
1.饿汉式
class Singleton{private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}private Singleton(){}
}
类在加载时,就会创建一个实例。在调用时,之间返回这一实例就好。
可以简单的认为,在程序启动时就创建了实例。
2.懒汉式
class Singletonlazy{public static Singletonlazy instance = null;public Singletonlazy getInstance(){if ( instance == null){instance = new Singletonlazy();}return instance;}private Singletonlazy(){}}
这是一段存在些许问题的代码,不过可以直观的感受到两者之间的区别。
在接下来,会对如上懒汉式代码进行优化。
3.优化懒汉式
我们先将懒汉式代码放置如下
class Singletonlazy{public static Singletonlazy instance = null;public Singletonlazy getInstance(){if ( instance == null){instance = new Singletonlazy();}return instance;}private Singletonlazy(){}}
在如上懒汉式的代码中,如果在多线程情况下,就会出现一些问题
在多线程中,线程是抢占式执行的。
那么就会给程序带来一些问题
由于线程的抢占式执行,虽说不会造成空间的浪费
但是时间的消耗确实客观存在的。
那么解决这个问题,就进行加锁操作。
public Singletonlazy getInstance(){synchronized (lock){if ( instance == null){instance = new Singletonlazy();}}return instance;}
这样加锁,就是将 if 和 new 打包成一个原子操作
但是这样也会出现问题
那么如何解决这个问题呢?
我们在锁的外层,在添加一个判断条件
public Singletonlazy getInstance(){if (instance == null) {synchronized (lock){if ( instance == null){instance = new Singletonlazy();}}}return instance;}
注意:
这里的两个if条件虽然内容一样,但是意义却完全不同
- 第一个if是判断是否要进行加锁操作
- 第二个if是判断是否要实例创建对象
如上代码已经解决了多线程情况下的线程安全问题。
也解决了执行效率的问题。
但是还存在一个问题
指令重排
4.指令重排
概念:
为了使处理器内部的运算单元能尽量被充分利用,处理器可能会对输入的代码进行乱序执行优化,处理器会在计算之后将乱序执行的结果重组,并确保这一结果和顺序执行结果是一致的,但是这个过程并不保证各个语句计算的先后顺序和输入代码中的顺序一致。这就是指令重排序。
通俗的说,就是在不改变代码逻辑的条件下,通过更改指令的执行顺序,来达到优化代码的效果。
举例:
在这一行代码中,一个创建对象实例的过程可以在指令的角度分为三步
- 申请内容空间
- 调用构造方法(对内存空间进行初始化)
- 把此时内存空间的地址,赋值给instance引用
在指令重排的优化下
可能有
1 --》3 --》 2
1 --》2 --》 3
这样两种情况
1是一定在第一步的,因为是要在保证代码逻辑的前提下,才能进行指令重排。
那么如何解决呢?
引入volatile
public static volatile Singletonlazy instance = null;
使用volatile关键字修饰的变量,可以保证其指令执行的顺序与程序指明的顺序一致,不会发生顺序变换
5.完整代码
class Singletonlazy{public static volatile Singletonlazy instance = null;public static Object lock = new Object();public Singletonlazy getInstance(){if (instance == null) {synchronized (lock){if ( instance == null){instance = new Singletonlazy();}}}return instance;}private Singletonlazy(){}}
以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞
相关文章:

【Java】单例模式
单例模式是面试中常考的设计模式之一 在面试中,面试官常常会要求写出两种类型的单例模式并解释原理 本文中,将从0到1的介绍单例模式究竟是什么 文章目录 ✍一、什么是设计模式?✍二、单例模式是什么?✍三、单例模式的类型**1.饿汉…...

Linux|从 STDIN 读取 Awk 输入
简介 在之前关于 Awk 工具的系列文章中,主要探讨了如何从文件中读取数据。但如果你希望从标准输入(STDIN)中读取数据,又该如何操作呢? 在本文中,将介绍几个示例,展示如何使用 Awk 来过滤其他命令…...
关于K8S集群中maste节点r和worker节点的20道面试题
1. 什么是Kubernetes(K8S)? Kubernetes(通常简称为K8S)是一种开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是Kubernetes的一些核心特性和优势: 自动化部署和扩展&…...

基于 OpenHarmony HistogramComponent 柱状图开发指南
1. HistogramComponent 组件功能介绍 1.1. 功能介绍 应用开发过程,用鸿蒙提供的 Component 自定义柱状图效果。 HistogramComponent 组件可以更快速实现一个简单的柱状图功能。 HistogramComponent 对外提供数据源,修改柱状图颜色,间距的…...
C语言指针相关
C语言指针int(*p)[4]如何理解? 快速搞懂 C/C 指针声明...
设计模式:责任链模式
责任链模式是一种行为设计模式,允许你将请求沿着一条链传递,直到一个对象处理它为止。这种模式包含了一些处理对象,每个对象都包含逻辑来处理特定类型的命令或请求。如果一个对象不能处理该请求,它就会将请求传递给链中的下一个对象,如此类推。 定义 责任链模式通过定义…...

【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.6p1(亲测无问题,建议收藏)
👨🎓博主简介 🏅CSDN博客专家 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入!…...
宁波中墙建材对于蒸压加气混凝土砌块2024年前景预测
宁波中墙建材对于蒸压加气混凝土砌块2024年前景预测 蒸压加气混凝土砌块(AAC)是一种轻质、多孔、保温隔热性能良好的建筑材料,广泛应用于建筑领域。2024年前景预测如下: 市场需求持续增长:随着全球对节能减排和绿色建筑…...

【神经网络】卷积神经网络CNN
卷积神经网络 欢迎访问Blog全部目录! 文章目录 卷积神经网络1. 神经网络概览2.CNN(Convolutional Neunal Network)2.1.学习链接2.2.CNN结构2.2.1.基本结构2.2.1.1输入层2.2.1.2.卷积层|Convolution Layers2.2.1.3.池化层|Pooling layers2.3…...

微信小程序-接入sse数据流并实现打字机效果( ChatGPT )
从流中获取的数据格式如下 小程序调用SSE接口 const requestTask wx.request({url: xxx, // 需要请求的接口地址enableChunked: true, // enableChunked必须为truemethod: "GET",timeout: 120000,success(res) {console.log(res.data)},fail: function (error) {//…...

深入了解iOS内存(WWDC 2018)笔记-内存诊断
主要记录下用于分析iOS/macOS 内存问题的笔记。 主要分析命令: vmmap, leaks, malloc_history 一:前言 有 3 种思考方式 你想看到对象的创建吗?你想要查看内存中引用对象或地址的内容吗?或者你只是想看看 一个实例有多大&#…...

《C语言深度解剖》(4):深入理解一维数组和二维数组
🤡博客主页:醉竺 🥰本文专栏:《C语言深度解剖》 😻欢迎关注:感谢大家的点赞评论关注,祝您学有所成! ✨✨💜💛想要学习更多数据结构与算法点击专栏链接查看&am…...
信号处理基础
傅里叶分析之掐死教程(完整版)更新于2014.06.06 先放一篇关于傅里叶变换以及欧拉公式的讲解在这里。后续会搬运到CSDN上。...

原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)
一、题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超…...

如何提升产品用户体验?4个工具+6张案例,让你快速吃透!
在数字时代的浪潮中,产品用户体验早已不再是简单的“好用”或“不好用”的评判标准,它不仅仅是功能的堆砌,更是情感的连接、智慧的体现。在这个竞争激烈的市场中,只有那些能够深入理解用户需求、精准把握用户心理的产品࿰…...
C++学习笔记九--模版
目录 前言 1.函数模版 1.函数模版的概念和定义 2.函数模版的实例化 2.类模版 1.类模版的概念和定义 2.类模版的实例化 3.示例代码 前言 这篇文章介绍下C中的模版,包括函数模版和类模版。 1.函数模版 在编程的过程中,编写函数都会考虑将其写成模版…...
19、差分矩阵
差分矩阵 题目描述 输入一个n行m列的整数矩阵,再输入q个操作,每个操作包含五个整数x1, y1, x2, y2, c,其中(x1, y1)和(x2, y2)表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上c。 请你将进行完…...

wordpress外贸独立站模板
wordpress外贸独立站模板 WordPress Direct Trade 外贸网站模板,适合做跨境电商的外贸公司官方网站使用。 https://www.waimaoyes.com/wangzhan/22.html...
HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP3.0的区别
一、HTTP/1.0 1996年5月,HTTP/1.0版本发布,为了提高系统的效率,HTTP/1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器…...

聚合DNS管理系统v1.0全新发布 域名解析管理系统
内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析,目前已支持的域名平台有:阿里云、腾讯云、华为云、西部数码、CloudFlare。本系统支持多用户&…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...