7.多线程之单例模式
单例模式
文章目录
- 单例模式
- 1. 什么是单例模式
- 2. 饿汉模式
- 3. 懒汉模式
- 3.1 单线程版:
- 3.2 多线程版
1. 什么是单例模式
单例模式是一种设计模式,常见的设计模式还有工厂模式、建造者模式等。
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。我们使用这些设计模式,相当于是前辈们在一些特殊的场景下总结出的经验,我们直接使用即可,相当于站在巨人的肩膀上编程!!!
单例模式是针对一些特定的类,只允许创建一个实例。为什么会有单例模式?因为引入单例模式后,在代码层面会有强制检查,不会允许创建出第二个实例,避免一些bug,人为检查是及其不可靠、不可控的。
单例模式有两种实现方式,分别是饿汉模式和懒汉模式,我们就这两种实现展开。
2. 饿汉模式
class Singleton{private static Singleton instance = new Singleton();public static Singleton getInstance() {return instance;}private Singleton() {}
}
public class Test {public static void main(String[] args) {Singleton sgt1 = Singleton.getInstance();Singleton sgt2 = Singleton.getInstance();System.out.println(sgt1 == sgt2);}
}
运行结果~~
true进程已结束,退出代码为 0
饿汉模式首先是线程安全的,对象在类加载时就会创建好,然后将构造方法设为私有,不允许再创建实例,最后通过公有方法将这个对象提供给外层调用。
这种模式为什么叫饿汉模式呢?其实也很简单,无论外层需不需要使用这个对象,在类加载时这个对象就已经创建了。而相比于饿汉模式,懒汉模式的做法则更加高效,在第一次实用类的时候,在进行创建。
3. 懒汉模式
3.1 单线程版:
class Singleton {private static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
为什么说这样实现懒汉模式是单线程版本?因为这个版本的懒汉模式在并发环境下,会产生线程安全问题,即线程不安全。
线程安全问题发生在首次创建实例时. 如果在多个线程中同时调getInstance 方法, 就可能导致创建出多个实例。一旦实例已经创建好了, 后面再多线程环境调用 getInstance 就不再有线程安全问题了(不再修改instance 了),因此枷锁(synchronized)可以一定程度上改善这个问题。

这个版本的懒汉模式,在多线程环境下,一但有其他线程在第一次创建对象时穿插(OS系统调度)进行执行,就可能会创建出多个实例。
3.2 多线程版
class SingletonLaze{private volatile static SingletonLaze instance = null;public static SingletonLaze getInstance() {if(instance == null) {synchronized(SingletonLaze.class) {if (instance == null) {instance = new SingletonLaze();}}}return instance;}private SingletonLaze() {}
在这个版本中对if判断进行枷锁,保证了创建对象时不会有其它线程穿插执行,在进一步给instance使用volatile修饰(保证可见性、顺序),从而保证了线程安全。我们进一步发现,只有在第一次进入时,才会需要创建对象,而如果每次都枷锁,就会降低程序的执行效率,所以我么在外部又嵌套了一层if。此处要注意的是这两层if虽然条件一样,但是含义却不一样。
锁竞争(枷锁解锁)的开销是比较大的,而懒汉模式只有在第一次才需要创建对象(产生锁竞争),后续就不在需要锁竞争了,也不必枷锁。
- 外层if :外层if是判断单例模式的对象是否创建出来,如果已经创建,则直接返回instance(instance被volatile修饰,不会产生内存可见性问题),不会产生锁竞争。
- 内层if:当线程第一次执行时会进入内层,竞争同一把锁,假设线程1拿到锁,就可以创建出对象,此时线程1执行完后,由于没内存可见性问题,其它线程就会发现instance已经不为空了,从而不会继续进入外层if竞争锁对象,降低了锁竞争的开销。
如果本篇文章对你有帮助,请点赞、评论、转发,你的支持是我创作的动力!!!
相关文章:
7.多线程之单例模式
单例模式 文章目录 单例模式1. 什么是单例模式2. 饿汉模式3. 懒汉模式3.1 单线程版:3.2 多线程版 1. 什么是单例模式 单例模式是一种设计模式,常见的设计模式还有工厂模式、建造者模式等。 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码…...
docker 常用指令
以下是一些常用的Docker指令: 构建镜像: docker build -t <image_name> <Dockerfile_directory>运行容器: docker run -d --name <container_name> <image_name>查看正在运行的容器: docker ps停止容…...
Numpy、Pandas、Matplotlib学习(更新ing...)
数据科学 一、Numpy二、Pandas三、Matplotlib参考链接 一、Numpy 在numpy中以np.nan表示缺失值,它是一个浮点数。 二、Pandas 1、如要选出col0在30到80之间的行中col3与col1之差为奇数的行,或者col2大于50中的行col3超过col1均值的行,可以…...
Linux-sdio接口
支持模式 4位模式: CMD:命令线,单向传输,由主机控制。 DAT0-DAT3:数据线,双向传输,由主机和外设共同控制。8位模式: CMD:命令线,单向传输,由主机…...
【MATLAB源码-第62期】基于蜣螂优化算法(DBO)的无人机三维地图路径规划,输出最短路径和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 蜣螂优化算法(Dung Beetle Optimization, DBO)是一种模拟蜣螂在寻找食物和进行导航的过程的优化算法。蜣螂是一种能够将粪球滚到合适地点的昆虫,它们利用天空中的光线和自身的感知能力来确…...
RealVNC Enterprise 7.7.0 Crack
RealVNC连接_旗舰产品 RealVNC Connect 是为需要强大安全性、弹性和安心的组织提供的远程访问解决方案。 设备访问 按需协助 随时随地安全访问和管理任何设备 通过安全的远程访问让您的组织保持联系,帮助您提高生产力并促进更广泛的协作。 随时随地安全远程访问和…...
Windows下Jenkins自动化部署SpringBoot应用
Windows下Jenkins自动化部署SpringBoot应用 1、下载安装包 下载地址: 一个是 msi 程序: https://mirrors.aliyun.com/jenkins/windows/ 一个是 war 程序: https://get.jenkins.io/war-stable/ https://mirrors.jenkins.io/war/ 这里我…...
Leetcode59螺旋矩阵2
代码: class Solution {public int[][] generateMatrix(int n) {if(n1){int[][] arr {{1}};return arr; }int[][] arr new int[n][n];int cnt1;int left 0,right n-1,top0,downn-1;while(left<right){for(int ileft;i<right;i){arr[top][i] cnt;}for(in…...
抖音很火的情侣飞行棋/真心话大冒险/情侣扫雷html网站源码带在线支付、代理分销等!
-------- 演示地址 -------- 演示地址:http://game.71.vy386.cn 演示后台:http://game.71.vy386.cn/admin 后台账号:admin888 后台密码:admin888 -------- 程序特色 -------- 1、完整的分销制度,可自定义多种不同…...
Word批量删除文档属性和个人信息方法图解
投标文件中设计敏感信息,在投标前必须删除,Word批量删除文档属性和个人信息方法图解: 右键word文件属性--详细信息,可以查看如下信息; 删除上述信息的办法: 1.打开word文件---文件 2.检查文档、检查文档 检…...
Kubernetes(K8s)从入门到精通系列之十八:使用 Operator Lifecycle Manager(OLM) 安装operator
Kubernetes从入门到精通系列之十八:使用 Operator Lifecycle Manager OLM 安装operator 一、先决条件二、安装operator三、示例:安装最新版本的 Operator四、示例:安装特定版本的 Operator 从运算符目录中安装运算符 通过 CatalogSource 将 …...
request、response请求转发和重定向
Request&Response request是请求对象,获取请求数据;response是响应对象,设置响应数据。 request获取请求数据 获取请求方式:request.getMethod(); 获取访问路径:request.getContextPath(); 获取UR…...
MySql学习路线
学习MySQL数据库的路线可以分为不同的阶段,从入门到高级,逐步掌握数据库管理和开发技能。以下是一个关于MySQL学习的路线: ### 初级阶段 1. **数据库基础知识**: - 学习数据库的基本概念,了解关系数据库管理系统&…...
Vue实现首页导航和左侧菜单,介绍mock.js并实现登录注册间的跳转,实现左侧栏折叠效果,优化Main.vue组件,使用mock.js生成随机响应数据
目录 1. mockjs 1.1 mockjs介绍 1.2 mockjs使用步骤 1.2.1 安装mockjs依赖 1.2.2 在项目中引入mockjs 1.2.3 创建目录和文件 1.2.4 为每个组件准备模拟数据 1.2.5 测试 1.2.6 前端调试 1.2.7 mockjs生成随机响应数据 1.2.8 根据不同响应,给出不同提示 2…...
汇总下之RobotFramework自动化框架的系列文章
总下之前分享的RobotFramework自动化框架的系列文章,有需要的同学可关注收藏 python自动化测试框架RobotFramework基础环境安装/使用(一) python自动化测试框架RobotFramework内置库BuiltIn介绍(二) python自动化测…...
0052【Edabit ★☆☆☆☆☆】Learn Lodash: _.drop, Drop the First Elements of an Array
0052【Edabit ★☆☆☆☆☆】Learn Lodash: _.drop, Drop the First Elements of an Array arrays Instructions According to the lodash documentation, _.drop creates a slice of an array with n elements dropped from the beginning. Your challenge is to write your…...
从无人机到实景三维海洋系统
无人机(比如大疆的测量无人机)测量的影像数据一般通过Pix4d处理以后生成OBJ或者FBX格式,在CesiumLab,转成3dtiles,就可以做成实景三维系统。Pix4d的教程在B站有很多,想了解的同学可直接在B站搜索学习&#…...
第二章前端开发ES6基础
目录 扩展运算符 概述 语法 应用 模板字符串 概述 应用 内置对象扩展 概述 数组扩展方法 字符串扩展方法 set数据结构 概述 基本使用 操作方法 遍历方法 认识symbol 概述 作用 基本使用 项目 扩展运算符 概述 扩展运算符(spread operator)是 ES6 中新…...
使用Python将PDF转为图片
将PDF转为图片能方便我们将文档内容上传至社交媒体平台进行分享。此外,转换为图片后,还可以对图像进行进一步的裁剪、调整大小或添加标记等操作。 用Python将PDF文件转JPG/ PNG图片可能是大家在一些项目中会遇到的需求,下面将详细介绍如何使用…...
JAVA 同城服务货运搬家小程序系统开发时应注意哪些?
在开发JAVA同城服务货运搬家小程序系统时,需要注意以下几点: 需求分析与设计:在开始开发前,需要对系统进行详细的需求分析与设计。这包括了对用户需求的理解、业务流程的梳理、数据库的设计以及界面设计等。确保系统的功能完善、…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
