多线程代码案例之单例模式

在这里插入图片描述

作者简介: zoro-1,目前大二,正在学习Java,数据结构,javaee等
作者主页: zoro-1的主页
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

多线程代码案例之单例模式

  • 单例模式
    • 饿汉式单例模式
    • 懒汉式单例模式

单例模式

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在单例模式中,类的实例化只会发生一次,并且可以在任何地方访问该实例。这种模式常用于需要共享资源的场景,例如数据库连接、线程池等。他分为饿汉式单例模式和懒汉式单例模式。

饿汉式单例模式

代码示例:

class Singletion{private static Singletion singletion=new Singletion();private Singletion(){}public static Singletion getInstance() {return singletion;}
}

饿汉式单例模式,没有线程安全问题,因为他的实例在类加载时就完成了

懒汉式单例模式

单线程下的懒汉式单例模式

public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

以上的代码在单线程情况下是安全的,但在多线程情况下就是存在问题

如何解决以上的问题:
1.假设现在有两个线程调用getInstance方法获取实例对象,如下:

public class Main {public static void main(String[] args) {Thread t=new Thread(()->{Singletion singletion=Singletion.getInstance();});Thread t1=new Thread(()->{Singletion singletion=Singletion.getInstance();});t.start();t1.start();}
}

以上的两个线程的执行顺序就有可能是:
在这里插入图片描述
这样就会导致被实例化两次,如果这个对象所需的空间很大这个操作是很危险的,所以就要加锁,一个线程在实例是另一个线程阻塞

 class Singleton {private static Singleton instance;private static Object loker=new Object();private Singleton() {}public static synchronized Singleton getInstance() {synchronized (loker) {if (instance == null) {instance = new Singleton();}}return instance;}
}

但以上代码也存在一定的问题就是当对象已经在t实例化后,t2就不必获取到锁了,这样会大大影响代码速度所以要在加锁上加一个判断条件,只有实例对象为null的时候才加锁

 class Singleton {private static Singleton instance;private static Object loker=new Object();private Singleton() {}public static synchronized Singleton getInstance() {if(instance==null) {synchronized (loker) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

现在已经差不多实现了,但还存在一个致命问题,就是指令重排序,这个问题是什么意思呢
指令重排序就是在执行以上代码时,jvm会将它进行优化,首先将以上代码原子化:
1.申请一段内存空间
2.在这个内存上调用构造方法创建实例
3.将这个内存地址赋值给变量 instance
通常都是123顺序执行,而jvm有可能将以上指令优化成132执行,这样的优化在单线程执行下没问题但在多线程代码下可能就会出现问题
在这里插入图片描述
假设在左边是t线程执行到实例 instance时执行了13两步就被t1线程挤走了,然后t1线程就会判断 instance为非null直接返回 instance,实际上还未真正实例化(2为指令),所以就可以使用volatile关键字解决这个问题他可以终止jvm的优化,按照123执行代码,就解决问题了

 class Singleton {private static volatile Singleton instance;private static Object loker=new Object();private Singleton() {}public static synchronized Singleton getInstance() {if(instance==null) {synchronized (loker) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
             今天的分享到这里就结束了,感谢大家支持

在这里插入图片描述

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

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

相关文章

【数据结构 04】单链表

一、链表简介 链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表在结构上的分类: 1. 带头结点或无头结点 2. 单向或双向 3. 循环或非循环 虽然链表有多种结构类型,但是我么在实际开发中…

C++ 结构体的构造函数

详解: ListNode(int x, ListNode* next) : val(x), next(next) {} 是 ListNode 结构体的构造函数。 ListNode(int x, ListNode* next):这是构造函数的声明部分。指定了构造函数的名称为 ListNode,参数列表包括一个整数 x 和一个指向 ListNode…

LLVM实战之交叉编译

所谓交叉编译指的是能够在一个平台(例如x86)编译并构建二进制文件,而在另一个平台(例如ARM)运行。编译二进制文件的机器称为主机(host),而运行生成的二进制文件的平台称为目标平台(target)。为相同平台(主机与目标机器相同)编译代码称为本机编译(native assembler…

【RT-DETR有效改进】Bi-FPN高效的双向特征金字塔网络(附yaml文件+完整代码)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本文给大家带来的改进机制是BiFPN双向特征金字塔网络,其是一种特征融合层的结构,也就是我们本文改进RT-DETR模型中的Neck部分,它的主要思想是通过多层级的特征金字塔和双向信息传递来提高精度。本文给大家带…

【C++】三角形(triangle)

题目描述 小魏有 3*n 根颜色两两不同的木棍,第i根的长度为a[i]。 小魏想把这3*n根木棍分成n组,每组三根,并且同一组的三根木棍可以组成一个三角形。 小魏想知道他有多少种不同的分组方案。认为两个分组方案是不同的,当且仅当两种方案组出来的…

Linux命令之 printf 详解

将字符串格式化输出 选项说明%s字符串%f浮点型%b相对应参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符被转义。%cASCII字符,显示想对应参数的第一个字符。%d%i 十进制整数%o不带正负号的八进制值%u不带正负号的十进制值%x不…

甘肃推动“安全石窟”建设,新技术助力文物预防性保护

一、甘肃用“智能化”技术让文物“重获新生” 文物保护与历史遗产和文化瑰宝的安全相关。甘肃有莫高窟、麦积山、炳灵寺等石窟寺,背负着历史的沧桑。但是,岁月侵蚀使这些文物状态变得令人堪忧。环境的微妙变化和温度和湿度的波动会对其导致不可逆转的伤…

Visual Studio 和Clion配置Cocos2d-x环境

Visual Studio 和Clion配置Cocos2d-x环境 首先,我就不贴图片的,懒得上传图床。懒。 开发环境: ​ 系统: Window11 ​ 编译器: CMake MSVC ​ 开发工具:Clion or Visual Studio ​ 请自行配置好,Python2.7,和Cma…

浮点数加、减运算步骤

一、浮点数介绍 1.1 浮点数格式: 精度位数格式单精度 float4个字节32位符号位1位,阶码8位,尾数23位双精度 double8个字节64位符号位1位,阶码11位,尾数52位 1.2 浮点的表示方法 浮点数在机器中的形式如下所示&#x…

C++数据结构与算法——链表

C第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更…

Linux初始相关配置

前言 在学完了Linux的相关基础命令后,在正式使用Linux系统之前,我觉得配置一些东西是很有意义的。 文章目录 前言1.权限配置,普通用户无法sudo提权2.vim配置3.vim其他操作4.动静态库5.gcc/g6.程序翻译的过程7.make/makefile8.cmake/CMakeLis…

【Unity3D小功能】Unity3D中设置Text行首不出现标点符号

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 在开发中会遇到Text的文本内容行首出现标点符号的情况&#xf…

vim 替换

在 Vim 编辑器中进行替换操作可以使用 :s 命令。下面是一些示例: 替换当前行第一个匹配到的字符串: :s/old/new/替换当前行所有匹配到的字符串: :s/old/new/g替换从当前行开始到文件末尾的所有匹配到的字符串: :%s/old/new/g替换整…

《动手学深度学习(PyTorch版)》笔记4.8

注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过。…

vue2 自定义webpack plugin 添加版本文件到public目录下/vue-config全局环境变量

在项目根目录创建version-plugin.js文件 // 引进node fs 模块 const fs require(fs)// 引进node path 模块 const path require(path)// webpack plugin class VersionPlugin {// 实例化传的参数constructor (options {}) {this.options optionsthis.isFinish false}// p…

实战教程:使用Spring Boot和Vue.js开发社区团购管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

使用AnimeGAN2将照片动漫化--入门

使用AnimeGAN2将照片动漫化--入门 1. 环境准备2. 使用3. 总结 1. 环境准备 首先下载AnimeGAN2:https://github.com/TachibanaYoshino/AnimeGANv2.git 然后使用conda 创建一个python3.6的环境conda create -n pyt36 python3.6: 创建一个requirements.txt文件&am…

前端模块化-AMD、CMD、CommonJS和UMD、ESM

前端模块化-AMD、CMD、CommonJS和UMD、ESM 背景CommonJSAMD和require.jsCMD和sea.jsUMD(Universal Module Definition - 通用模块定义)ES6 ModuleES6 模块与 CommonJS 模块的差异总结 背景 在NodeJS之前,由于没有过于复杂的开发场景&#xf…

生信学院|02月02日《云端设计一体化平台—3DEXPERIENCE》

课程主题:云端设计一体化平台—3DEXPERIENCE 课程时间:2024年02月02日 14:00-14:30 主讲人:郭俊辰 生信科技 解决方案顾问 1、云产品发展趋势 2、3DExperience产品的介绍 3、3DExperience DEMO演示 请安装腾讯会议客户端或APP&#xff…

记一次无法ping通Cisco switch处理

网络小白,仅仅在工作中需要telnet到switch。奈何之前不知什么原因一直无法ping通该switch,很久只能使用串口连接来配置了。而今遇到了使用脚本telnet switch的场景,不得不再次面对这个问题。 首先还是使用串口来看switch是否拿到ip&#xff…