【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->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() {}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32入门教程--ADC模拟-数字转换器

ADC(Analog-Digital Converter)模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转你换位内存中存储的数字变量,建立模拟电路到数字电路的桥梁。 12位逐次逼近型ADC,1us转换时间 输入电压范围:0-3.3V转换结果范围…

Pyramidal Flow使用指南:快手、北大、北邮,开源可免费商用视频生成模型,快速上手教程

什么是 Pyramidal Flow? Pyramidal Flow 是由快手科技、北京大学和北京邮电大学联合推出的开源视频生成模型,它是完全开源的,发布在 MIT 许可证下,允许商业使用、修改和再分发。该模型能够通过文本描述生成最高10秒、分辨率为128…

Embedding 模型和Model 批量推理和多卡部署

批量推理 多卡部署 使用huggingface 【AI大模型】Transformers大模型库(七):单机多卡推理之device_map_transformers多卡推理-CSDN博客 首先用 CUDA_VISIBLE_DEVICES1,2,3 python 或者os.environ["CUDA_VISIBLE_DEVICES"] &q…

风力发电场的“守护神”

摘要:作为清洁能源之一,风力发电场近几年装机容量快速增长。8月17日,国家能源局发布1-7月份全国电力工业统计数据。截至7月底,全国累计发电装机容量约27.4亿千瓦,同比增长11.5%。其中,太阳能发电装机容量约…

TCP simultaneous open测试

源代码 /*************************************************************************> File Name: common.h> Author: hsz> Brief:> Created Time: 2024年10月23日 星期三 09时47分51秒**********************************************************************…

转录组上游分析流程(三)

环境部署——数据下载——查看数据(非质控)——数据质控——数据过滤(过滤低质量数据) 测序得到的原始序列含有接头序列和低质量序列,为了保证信息分析的准确性,需要对原始数据进行质量控制,得到高质量序列(Clean Reads),原始序列…

Linux系统块存储子系统分析记录

1 Linux存储栈 通过网址Linux Storage Stack Diagram - Thomas-Krenn-Wiki-en,可以获取多个linux内核版本下的存储栈概略图,下面是kernel-4.0的存储栈概略图: 2 存储接口、传输速度 和 协议 2.1 硬盘 《深入浅出SSD:固态存储核心…

(二十三)Java反射

1.反射概念 反射允许对成员变量,成员方法和构造方法的信息进行编程访问,通俗理解就是允许从类里面拿东西,用途有提示词等,如下所示都是通过反射实现的 所以,学习反射就是学习从字节码class文件中获取成员信息并且对其…

stable diffusion WEBUI Brief summary

1,rembg(去除背景-》蒙版) import rembg from PIL import Image, ImageOps import numpy as np# 打开图像 input_path "./p_6258838.jpg" input_image Image.open(input_path)# 移除背景,得到带有透明背景的图像 output_image rembg.remove…

利用大模型进行复杂决策制定:PlanRAG技术的研究

人工智能咨询培训老师叶梓 转载标明出处 有效的决策制定对于组织的成功至关重要。传统的决策支持系统虽然在数据分析和决策辅助方面取得了一定的进展,但在处理需要复杂数据分析的决策问题时仍显不足。为了解决这一问题,来自韩国高等科学技术院&#xff…

fpga系列 HDL: 竞争和冒险 01

卡诺图是一种逻辑化简工具,用来在布尔函数的最小项和形式中,找到冗余项并实现逻辑化简。也可用于HDL中竞争和冒险的判断。 最小项 任何一个逻辑函数都能化简为最小项的和的形式对于 n 个变量的布尔表达式,每个变量都必须以原变量&#xff0…

Zabbix企业级分布式监控环境部署

“运筹帷幄之中,决胜千里之外”。在IT运维中,监控占据着重要的地位,按比例来算,说占30%一点也不为过。对IT运维工程师来说,构建一个真正可用的监控告警系统是一项艰巨的任务。在监控系统的开源软件中,可供选…

基于模型划分的云边协同推理算法

摘要 在网络状态和任务需求的动态变化下,为减少模型推理时延和计算成本,在软件定义网络( Software Defined Network,SDN) 中提出了一种基于模型划分的云边协同推理算法。通过构建复杂度预测器分配任务执行环境,采用深度Q网络(Dee…

国产标准数字隔离器的未来---克里雅半导体

标准数字隔离器是电信号隔离技术的重要组成部分,近年来取得了重大进展。随着工业自动化、汽车电子和电信等行业对更高性能的需求不断增长,国内数字隔离器制造商正在稳步赶上全球标准。本文讨论了数字隔离器技术的新兴趋势、材料创新的影响,以…

网站建设中需要注意哪些安全问题?----雷池社区版

服务器与应用安全指南 1. 服务器安全 1.1 操作系统安全 及时更新补丁:确保操作系统始终安装最新补丁,以防范系统漏洞。例如,Windows Server 定期推送安全更新,修复如远程代码执行等潜在威胁。优化系统服务配置:关闭不…

一家医药企业终止,收入依赖阿里健康,学术推广费快赶上净利润

知原药业终止原因如下:知原药业报告期三年的推广费用超3亿元,快赶上这三年累计3.68亿元的净利润了,交易所质疑其学术推广费单价合理性、是否存在销售返利。并且,公司研发费用率低于行业平均水平,在电商平台营销主要依赖…

pytorh学习笔记——cifar10(三)模仿VGGNet创建卷积网络

VGG16是由牛津大学视觉几何组(Visual Geometry Group)提出的一种深度卷积神经网络模型。 VGGNet 探索了卷积神经网络的深度与其性能之间的关系,成功地构筑了 16~19 层深的卷积神经网络,同时拓展性又很强,迁移到其它图片…

【LeetCode】11.盛最多水的容器

思路: 利用双指针法进行移动,一个在头一个在尾,此时宽度最宽,当宽度缩小时,高度发生变化,从而可以找到最大值。 代码: int maxArea(int* height, int heightSize) {int* left height;int* …

仿真学习 | Fluent版本迭代一览及选择指南

在计算机辅助工程(CAE)领域,软件版本的更新迭代,影响了工程师的工作效率、工作习惯和仿真精度,“如何选择软件版本”也永远是摆在每个初学者面前的第一个难题。 计算流体动力学(CFD)领域的领军…

嵌入式工程师必备——NTC曲线拟合

最近搞了一下NTC热敏电阻,打算和大家分享一下; 首先看NTC手册,25℃时是5K,温度系数B是3470,有一些NTC会直接给出公式,那种直接按照手册计算就好; 1、下面是温度和阻值对照表,这个表…