【JavaEE】【多线程】单例模式
目录
- 一、设计模式
- 1.1 单例模式
- 1.1.1 饿汉模式
- 1.1.2 懒汉模式
- 1.2 线程安全问题
- 1.3 懒汉模式线程安全问题的解决方法
- 1.3.1 原子性问题解决
- 1.3.2 解决效率问题
- 1.3.3 解决内存可见性问题和指令重排序问题
一、设计模式
在讲解案例前,先介绍一个概念设计模式:就是大佬们把一些经典问题整理出来,针对这些场景,大佬们总结出固定的套路,来解决这些问题。就类似棋谱一样的概念。
1.1 单例模式
单例模式:就是强制要求,某个类在某个程序中,只能有一个实例,只能new一个对象。比如在开发中一个类存有很大的数据量,new两三次就把空间占满了,这时就可以使用单例模式了。
1.1.1 饿汉模式
饿:指尽早创建对象。
饿汉模式:类对象在类中使用static修饰为静态成员,并将构造方法使用private修饰私有化。
下面写一个简单饿汉模式代码:
class SingletonHunger {private static SingletonHunger instance = new SingletonHunger();public static SingletonHunger getInstance() {return instance;}private SingletonHunger() {}
}
1.1.2 懒汉模式
懒:指尽量晚创建对象,甚至不创建。
懒汉模式:类对象在类中使用static修饰为静态成员,并赋值为null,并将构造方法使用private修饰私有化,只不过是在get方法中去实例化。
下面写一个简单懒汉模式代码:
class SingletonLazy {private static SingletonLazy instance = null;public static SingletonLazy getInstance() {if(instance == null) {instance = new SingletonLazy();}return instance;}private SingletonLazy() {}
}
1.2 线程安全问题
在多线程代码中我们要考虑上诉两中模式是否存在线程安全问题。
- 我们看饿汉模式中在类创建的同时直接就将对象实例化好了,后续就一个return操作,相当于只是读取操作,而读取操作是不涉及线程安全问题的,所以饿汉模式不存在线程安全问题。
- 我们看懒汉模式中,是先进行一次判断操作,在进行实例化,那这样就涉及到不是原子性的了,所以懒汉模式存在线程安全问题。
1.3 懒汉模式线程安全问题的解决方法
1.3.1 原子性问题解决
这样的问题我们使用synchronized加锁操作就行。
- 可以加在get方法上,以当前类对象作为锁对象;
- 也可以将if包含起来。
class SingletonLazy {private static SingletonLazy instance = null;private static Object block = new Object();public static SingletonLazy getInstance() {synchronized(block){if(instance == null) {instance = new SingletonLazy();}return instance;}}private SingletonLazy() {}
}
1.3.2 解决效率问题
在我们上面加了锁之后,创建完对象之后每次在调用get方法的时候,还是会加锁,这就会导致产生锁竞争,线程阻塞问题影响效率。
这种解决方式就是在这之前在判断一次对象是否为空就行了。
class SingletonLazy {private static SingletonLazy instance = null;private static Object block = new Object();public static SingletonLazy getInstance() {if(instance == null) {synchronized (block) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}private SingletonLazy() {}
}
这可能两个相同的判空语句放在一起,感觉会有点别扭,但是其实两者的作用是天差地别的:
- 第一个语句是防止加了锁之后,在竞争锁导致效率低;
- 第二个语句是为了保证判断和实例是原子的。
1.3.3 解决内存可见性问题和指令重排序问题
编译器是否会进行优化导致内存可见性问题的出现,是不一定的,人为也不好预测。所以在对象前面加上volatile修饰就好。
指令重排序:是编译器对代码执行的指令的顺序进行调整,以达到优化的目的。
就像去买东西一样,先买什么后买什么的顺序也会影响买东西花费的时间。
而在上诉代码中instance = new SingletonLazy();这个语句就有可能触发指令重排序问题。
这条语句主要执行三条主要指令;
- 申请内存空间;
- 在空间上构造对象,也就是实例化对象;
- 将内存空间的"首地址"赋值给引用变量。
正常的执行顺序是1->2->3,但是由于指令重排序会出现1->3->2的情况,
这样先执行了3操作,该对象就不为null了,其它线程就可以对这个还没有实例化的对象进行操作了。这也引发了线程不安全问题。
这个问题的解决方法也是在对象前面加上volatile修饰就好。
volatile主要作用是:
- 确保从内存中读取数据,避免内存可见性问题;
- 确保读取和修改操作不会触发指令重排序问题。
代码:
class SingletonLazy {private volatile static SingletonLazy instance = null;private static Object block = new Object();public static SingletonLazy getInstance() {if (instance == null) {synchronized (block) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}private SingletonLazy() {}
}
相关文章:
【JavaEE】【多线程】单例模式
目录 一、设计模式1.1 单例模式1.1.1 饿汉模式1.1.2 懒汉模式 1.2 线程安全问题1.3 懒汉模式线程安全问题的解决方法1.3.1 原子性问题解决1.3.2 解决效率问题1.3.3 解决内存可见性问题和指令重排序问题 一、设计模式 在讲解案例前,先介绍一个概念设计模式ÿ…...
Java.6--多态-设计模式-抽象父类-抽象方法
一、多态 1.定义--什么是多态? a.同一个父类的不同子类对象,在做同一行为的时候,有不同的表现形式,这就是多态。(总结为:一个父类下的不同子类,同一行为,不同表现形式。࿰…...
JAVA Maven 的安装与配置
一、下载地址 官方网站:Maven – Download Apache Maven 我这里是3.8.6版本 二、安装步骤 maven安装之前要先安装jdk,请确保你的系统已经安装了jdk环境。 1.将下载好的 Maven 进行解压 apache-maven-3.6.8-bin.zip 2.配置本地仓库:修改 conf/settin…...
【程序分享】PCB元件坐标对齐工具 V1.3
↑↑↑点击上方蓝字,关注我们! “PCB元件坐标对齐工具 V1.3”脚本程序在PCB文档中将元件的坐标自动移动到参考圆弧的中心,参考圆弧支持机械层1层和禁止布线层,参考图元的位置任意,不局限于栅格位置。 程序会自动…...
[bug] vllm 0.6.1 RuntimeError: operator torchvision::nms does not exist
[bug] vllm 0.6.1 RuntimeError: operator torchvision::nms does not exist 环境 python 3.10 torch 2.4.0cu118 torchvision 0.19.0cu118 vllm 0.6.1.post2cu118问题详情 if torch._C._d…...
处理Hutool的Http工具上传大文件报OOM
程序环境 JDK版本: 1.8Hutool版本: 5.8.25 问题描述 客服端文件上传主要代码: HttpRequest httpRequest HttpUtil.createPost(FILE_UPLOAD_URL); Resource urlResource new UrlResource(url, fileName); httpRequest.form("file&q…...
transforms的使用
示例代码 from PIL import Image from torch.utils.tensorboard import SummaryWriter from torchvision import transforms#打开该图片 img_path"hymenoptera_data/val/bees/10870992_eebeeb3a12.jpg" imgImage.open(img_path) writerSummaryWriter("logs&quo…...
python-PyQt项目实战案例:制作一个视频播放器
文章目录 1. 关键问题描述2. 通过OpenCV读取视频/打开摄像头抓取视频3. 通过PyQt 中的 QTimer定时器实现视频播放4. PyQt 视频播放器实现代码参考文献 1. 关键问题描述 在前面的文章中已经分享了pyqt制作图像处理工具的文章,也知道pyqt通过使用label控件显示图像的…...
反向传播的微积分原理 | Chapter 4 | Deep Learning | 3Blue1Brown
目录 前言1. 简介2. 神经网络中的链式法则3. 微积分的计算4. 公式含义5. 代价函数对权重偏置的敏感度6. 多个神经元的情形7. 回顾相关资料结语 前言 3Blue1Brown 视频笔记,仅供自己参考 这个章节主要来深度讲解反向传播中的一些微积分理论 官网:https://…...
matlab读取excel表格
使用matlab读取excel表格中的数据 使用推荐代码读取excel表格中的数据 path "C:\Users\24975\Desktop\503\GUI展示案例\Tx_20_0_Rx_40_90_0.1_95_L.xlsx";%文件路径 data readtable(path,Sheet,Sheet1,ReadRowNames,false,ReadVariableNames,false,Ra…...
基于springboot+vue实现的助学兼职系统(源码+L文+ppt)4-092
基于springbootvue实现的助学兼职系统(源码L文ppt)4-092 第4章 系统设计 4.1 总体功能设计 一般学生、招聘公司和管理者都需要登录才能进入助学兼职系统,使用者登录时会在后台判断使用的权限类型,包括一般使用者和管理者,一般使…...
⌈ 传知代码 ⌋ 农作物病害分类(Web端实现)
💛前情提要💛 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间,对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…...
CMU生成式人工智能大模型:从入门到放弃(九)
引言 在前面的系列博客中,我们深入探讨了生成式对抗网络(GANs)和变分自编码器(VAEs)等生成式模型。今天,我们将探索扩散模型(Diffusion Models)的进一步应用,并讨论在上…...
HTML基础总结
一、简介 HTML(HyperText Markup Language)即超文本标记语言,是用于创建网页的标准标记语言。它通过使用各种标签来定义网页的结构和内容,告诉浏览器如何显示网页。HTML 文档由标签和文本组成,标签用于描述文本的性质…...
EXCELL中如何两条线画入一张图中,标记坐标轴标题?
1,打开excel,左击选中两列, 2,菜单栏>“插入”>”二维折线图”选中一个 3,选中出现的两条线中的一条右击>最下一行,“设置数据系列格式” 4,右测“系列选项中”>点击“次坐标轴” 5…...
Zabbix企业级分布式监控环境部署
“运筹帷幄之中,决胜千里之外”。在IT运维中,监控占据着重要的地位,按比例来算,说占30%一点也不为过。对IT运维工程师来说,构建一个真正可用的监控告警系统是一项艰巨的任务。在监控系统的开源软件中,可供选…...
水轮发电机油压自动化控制系统解决方案介绍
在现代水电工程中,水轮机组油压自动化控制系统,不仅直接关系到水轮发电机组的安全稳定运行,还影响着整个水电站的生产效率和经济效益。 一、系统概述 国科JSF油压自动控制系统,适用于水轮发电机组调速器油压及主阀(蝶…...
今天不分享技术,分享秋天的故事
引言 这个爱情故事好像是个悲剧,你说的是婚姻。爱情没有悲剧,对爱者而言,爱情怎么会是悲剧呢。对春天而言,秋天是它的悲剧吗。结尾是什么,等待,之后呢,没有之后。或者说,等待的结果…...
转录组上游分析流程(三)
环境部署——数据下载——查看数据(非质控)——数据质控——数据过滤(过滤低质量数据) 测序得到的原始序列含有接头序列和低质量序列,为了保证信息分析的准确性,需要对原始数据进行质量控制,得到高质量序列(Clean Reads),原始序列…...
excel判断某一列(A列)中的数据是否在另一列(B列)中
如B列如果有7个元素,在A列右边的空白列中,输入如下公式: COUNTIF($B$1:$B$7,A1), 其中,$B$1:$B$7代表A列中的所有数据即绝对范围,A1代表B列中的一个单元格....
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
