当前位置: 首页 > news >正文

解决多线程环境下单例模式同时访问生成多个实例

如何满足单例:1.构造方法是private、static方法、if语句判断

①、单线程

Single类

//Single类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {System.out.println("创建一次");}public static LazySingleton GetInstance() {//当多线程来临的时候判断是否为null,此时instance就是临界资源,会实例化多个if (instance == null) {instance = new LazySingleton();}return instance;}
}
//客户端代码
public class Main {public static void main(String[] args) {LazySingleton s1= LazySingleton.GetInstance();LazySingleton s2=  LazySingleton.GetInstance();if(s1==s2){System.out.println("两个对象是相同的实例");}}
}

运行结果:

这样的话就满足了单例的效果,保证只实例化一个类,因为LazySingleton封装它的唯一实例,这样它可以严格地控制客户怎样访问它以及何时访问它。简单地说就是对唯一实例的受控访问。客户端通过那唯一可以访问的GetInstance方法来访问那一个实例。但如果是多个线程同时调用GetInstance方法,同时运行到了GetInstance方法这儿,它们都会去判断有没有被实例化,判断都为True,那样的话就创建了两个实例,就违背了单例模式,不是一个单例。看下多线程下的单例:

②、多线程

单例类

public class LazySingleton {private static LazySingleton instance;private LazySingleton() {System.out.println("创建一次");}public static LazySingleton GetInstance() {//当多线程来临的时候判断是否为null,此时instance就是临界资源,会实例化多个if (instance == null) {instance = new LazySingleton();}return instance;}
}

main函数

public class Main {public static void main(String[] args) {Runnable r=()->{LazySingleton s1= LazySingleton.GetInstance();LazySingleton s2=  LazySingleton.GetInstance();if(s1==s2){System.out.println("两个对象是相同的实例");}};//两个线程Thread t1= new Thread(r);Thread t2= new Thread(r);t1.start();t2.start();}
}

运行结果:

我们会发现对象被创建了两次,我们通过调试发现s1和s2两个对象的地址实际上是不一样的:

当线程t1刚执行完if (instance == null)判断之后时间片到了,t2线程执行完if (instance == null)判断之后就进入方法体生成了实例,此时t1线程又获得了时间片,t1会接着上次中断的地方继续执行,t1线程便会进入方法体又生成了一个新的实例,此时t1和t2线程各生成了一个实例

如何解决这样一个问题呢?

添加锁,当线程位于临界区的时候就上锁,其他线程来临的时候只能在外排队等待。

③、多线程单例——单锁

单例类

package com.example;public class LazySingleton {private static LazySingleton instance;private LazySingleton() {System.out.println("创建一次");}public static LazySingleton GetInstance() {//当多线程来临的时候判断是否为null,此时instance就是临界资源,会实例化多个//方法:加锁-把判断的这部分逻辑上锁synchronized ("") {if (instance == null) {instance = new LazySingleton();}}return instance;}}

main函数

public class Main {public static void main(String[] args) {Runnable r=()->{LazySingleton s1= LazySingleton.GetInstance();LazySingleton s2=  LazySingleton.GetInstance();if(s1==s2){System.out.println("两个对象是相同的实例");}};//两个线程Thread t1= new Thread(r);Thread t2= new Thread(r);t1.start();t2.start();}
}

运行结果:

发现对象创建了一次。在同一时刻加了锁的那部分程序只有一个线程可以进入,我们可以让最先进入的那个线程先上一把锁,创建实例。后面在进入的线程就不会再去创建对象实例了,因为第一名来的线程已经创建了,你这个判断的结果是False,自然无法创建了。这样的话就保证了多个线程同时访问的话不会有多个实例化。解决了上面单实例带来的问题。但每次进入的线程都需要先加锁在判断,我都还不知道有没有创建过这个实例呢你就让我加锁,第一名已经实例化过了,我进去再加锁,在判断一次,如果有上百个线程同时访问呢,这样的工作重复上百次,不是很影响我这个程序的性能吗?我们就可以用到双重锁定来解决这个问题

④、多线程——双重锁(Double-Check Locking)

package com.example;public class DoubleLockSingleton {private static DoubleLockSingleton instance;private DoubleLockSingleton() {System.out.println("实例化了一次");}public static DoubleLockSingleton GetInstance() {//第一层判断:先判断实例是否存在,不存在再加锁处理if (instance == null) {synchronized ("") {//第二层判断if (instance == null) {instance = new DoubleLockSingleton();}}}return instance;}
}

通过这样两重的判断,进入的线程不用每次都加锁,只是在实例未被创建的时候在加锁处理。同时也保证多线程的安全。

相关文章:

解决多线程环境下单例模式同时访问生成多个实例

如何满足单例:1.构造方法是private、static方法、if语句判断 ①、单线程 Single类 //Single类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例 public class LazySi…...

转转闲鱼交易猫源码搭建

后台一键生成链接,独立后台管理 教程:修改数据库config/Conn.php 不会可以看源码里有教程 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...

设计模式精华版汇总

以下是个人整理的设计模式汇总,将会持续更新工作和面试中经常用到的设计模式。 设计模式-装饰者模式(包装模式)- 案例分析和源码分析​​​​​​ 设计模式-代理模式:控制访问的设计模式 - 案例分析 设计模式-门面模式&#xf…...

uniapp实现带参数二维码

view <view class"canvas"><!-- 二维码插件 width height设置宽高 --><canvas canvas-id"qrcode" :style"{width: ${qrcodeSize}px, height: ${qrcodeSize}px}" /></view> script import uQRCode from /utils/uqrcod…...

金融行业软件测试面试题及其答案

下面是一些常见的金融行业软件测试面试题及其答案&#xff1a; 1. 什么是金融行业软件测试&#xff1f; 金融行业软件测试是针对金融领域的软件系统进行验证和确认的过程&#xff0c;旨在确保软件在安全、稳定、可靠和符合法规要求的条件下运行。 2. 解释一下金融软件中的风险…...

强化学习QLearning 进行迷宫游戏和代码

强化学习是机器学习里面的一个分支。它强调基于环境而探索行动、学习&#xff0c;以取得最大化的预期收益。其灵感来源于心理学中的行为主义理论&#xff0c;既有机体如何在环境给予的奖励或者惩罚的刺激下&#xff0c;逐步形成对刺激的预期&#xff0c;产生能够最大利益的习惯…...

Vue2 第九节 过滤器

&#xff08;1&#xff09;定义&#xff1a;对要显示的数据进行特定格式化后再显示 &#xff08;2&#xff09;语法&#xff1a; ① 注册过滤器 1&#xff09;Vue.filter(name, callback) 全局过滤器 2&#xff09; new Vue({filters:{}}) 局部过滤器 ② 使用过滤器 1&…...

Swift 对象数组去重

使用 reduce 方法去重 使用 reduce 方法结合 contains 方法可以实现去重。reduce 方法用于将数组的元素进行累积计算&#xff0c;而 contains 方法用于检查元素是否已经存在于结果数组中。 struct SearchRecord: Equatable {let id: Intlet name: String }let records [Sear…...

代码随想录算法训练营day52 300.递增子序列 674.最长连续递增子序列 718.最长重复子数组

题目链接300.递增子序列 class Solution {public int lengthOfLIS(int[] nums) {int[] dp new int[nums.length];Arrays.fill(dp, 1);for(int i 0; i < nums.length; i){for(int j 0; j < i; j){if(nums[i] > nums[j]){dp[i] Math.max(dp[i], dp[j] 1);}}}int r…...

Android 面试题 虚拟机、进程、线程 七

&#x1f525; 安卓虚拟机 &#x1f525; 虽然Android程序是使用Java语言开发的&#xff0c;当然&#xff0c;现在也可以使用kotlin语言。但是实际上我们开发出来的Android程序并不能运行在JVM上&#xff0c;而是只能运行在一个类似JVM的Android虚拟机上。Android虚拟机有两种&…...

Flutter 状态组件 InheritedWidget

Flutter 状态组件 InheritedWidget 视频 前言 今天会讲下 inheritedWidget 组件&#xff0c;InheritedWidget 是 Flutter 中非常重要和强大的一种 Widget&#xff0c;它可以使 Widget 树中的祖先 Widget 共享数据给它们的后代 Widget&#xff0c;从而简化了状态管理和数据传递…...

<C++> 入门

在学习完C语言的基础上&#xff0c;继续开始C的学习。 C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式等。熟悉C语言之后&#xff0c;对C学习有一定的帮助。 1. 补充C语言语法的不足&#xff0c;以及C是如…...

政策加持智能家居市场,涂鸦赋能客户打造“以人为本”智能生活新方式

7月18日&#xff0c;商务部等13部门联合发布了《关于促进家居消费若干措施的通知》&#xff08;以下简称《通知》&#xff09;&#xff0c;《通知》指出&#xff0c;创新培育智能消费&#xff0c;支持企业运用物联网、云计算、人工智能等技术&#xff0c;着重加快智能家电、智能…...

安全渗透初级知识总结-2

CIA三原则&#xff1a;保密性&#xff0c;完整性&#xff0c;可用性 https:解决了安全传输问题 核心技术&#xff1a;用非对称加密传输对称加密的秘钥&#xff0c;然后用对称秘钥通信 抓包&#xff1a;Wireshark、tshark、tcpdump valueof方法是一个所有对象都拥有的方法&am…...

数学建模的32种常规方法及案例代码

比赛期间整理的数学建模的32种常规方法及案例代码友情分享&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/18uDr1113a0jhd2No8O1Nog 提取码&#xff1a;xae5 在数学建模中&#xff0c;常规算法是指那些被广泛应用于各种问题求解的经典算法。这些算法覆盖了不同的数学…...

【Django+Vue】英文成绩管理平台--20230727

能够满足大部分核心需求&#xff08;标绿&#xff09;&#xff1a;报表部分应该比较难。 项目地址 前端编译 https://gitlab.com/m7840/toeic_vue_dist Vue源码 https://gitlab.com/m7840/toeic_vue Django源码 https://gitlab.com/m7840/toeic_python 项目架构 流程 …...

栈-模拟栈

实现一个栈&#xff0c;栈初始为空&#xff0c;支持四种操作&#xff1a; push x – 向栈顶插入一个数 x&#xff1b; pop – 从栈顶弹出一个数&#xff1b; empty – 判断栈是否为空&#xff1b; query – 查询栈顶元素。 现在要对栈进行 M 个操作&#xff0c;其中的每个…...

图观| 从王宝强、费翔、阿汤哥等新上映的电影聊聊图的智能推荐场景

从技术的视角来看&#xff0c;推荐系统本质上是在用户需求不明确的情况下&#xff0c;从海量的信息中为用户过滤出他可能感兴趣的信息的一种技术手段。 我们日常接触到的智能推荐有&#xff1a; 电商网站&#xff1a;如淘宝、天猫、京东、Amazon…… 生活服务&#xff1a;如美…...

Redis系列一:介绍

介绍 The open source, in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker. 相关资源 Redis 官网&#xff1a;https://redis.io/ 源码地址&#xff1a;https://github.com/redis/redis Redis 在线测试&#…...

Java 设计模式 - 单例模式 - 保证类只有一个实例

单例模式 - 保证类只有一个实例 为什么使用单例模式&#xff1f;单例模式的实现方式1. 饿汉式&#xff08;Eager Initialization&#xff09;2. 懒汉式&#xff08;Lazy Initialization&#xff09;3. 双重检查锁&#xff08;Double-Checked Locking&#xff09;4. 静态内部类&…...

NotebookLM时间线创建全流程拆解(从零到专业级时间叙事)

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;NotebookLM时间线创建全流程拆解&#xff08;从零到专业级时间叙事&#xff09; NotebookLM 的时间线&#xff08;Timeline&#xff09;功能并非内置独立模块&#xff0c;而是依托其“脚注驱动叙事”机制&am…...

HarmonyOS ArkUI实战:从零构建购物社交应用UI界面

1. 项目概述与核心价值如果你正在学习HarmonyOS应用开发&#xff0c;或者已经从其他移动端框架&#xff08;如Android、Flutter&#xff09;转过来&#xff0c;那么构建一个美观、交互流畅的UI界面&#xff0c;往往是上手实践的第一步&#xff0c;也是最直观检验学习成果的一步…...

蛋白质基础模型:从AlphaFold2到Chai-1的范式跃迁

1. 项目概述&#xff1a;一场悄然发生的蛋白质结构预测范式迁移最近在实验室跑完第7轮Chai-1的微调任务后&#xff0c;我盯着屏幕上跳出来的pLDDT值曲线&#xff0c;突然意识到&#xff1a;我们正在经历的不是一次工具升级&#xff0c;而是一场底层建模逻辑的彻底重写。标题里提…...

modelzoo:昇腾 NPU 的“模型仓库”

modelzoo&#xff1a;昇腾 NPU 的“模型仓库” 之前帮朋友看模型训练的代码&#xff0c;发现他自己手写了很多模型&#xff08;ResNet50/BERT/LLaMA2 等&#xff09;——光写模型定义就写了 5,000 行&#xff0c;而且还不一定对。 我告诉他&#xff1a;不用手写&#xff0c;用 …...

什么,锐捷极简以太彩光一张网竟然有两幅面孔?

在园区网络的建设中&#xff0c;我们常常面临一个两难选择&#xff1a;教学或办公楼需要大带宽&#xff0c;宿舍或病房楼需要弹性带宽。如果分别建两张网&#xff0c;成本翻倍、运维复杂。 锐捷极简以太彩光方案给出的答案是&#xff1a;一张物理网络&#xff0c;同时融合两种…...

中性点不接地系统或中性点经消弧线圈接地系统的小电流接地故障仿真研究(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 &#x1f381…...

Source Sans 3:让数字界面阅读体验焕然一新的开源字体解决方案

Source Sans 3&#xff1a;让数字界面阅读体验焕然一新的开源字体解决方案 【免费下载链接】source-sans Sans serif font family for user interface environments 项目地址: https://gitcode.com/gh_mirrors/so/source-sans 你是否曾经在设计网页或应用时&#xff0c;…...

《QGIS空间数据处理与高级制图》022:融合后拓扑错误预检查

作者:翰墨之道,毕业于国际知名大学空间信息与计算机专业,获硕士学位,现任国内时空智能领域资深专家、CSDN知名技术博主。多年来深耕地理信息与时空智能核心技术研发,精通 QGIS、GrassGIS、OSG、OsgEarth、UE、Cesium、OpenLayers、Leaflet、MapBox 等主流工具与框架,兼具…...

【ElevenLabs云南话语音落地实战】:20年语音AI专家亲授3步适配方言模型,避开92%开发者踩过的声学对齐陷阱

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs云南话语音落地实战导论 云南话作为西南官话的重要分支&#xff0c;具有声调丰富、语流连贯、地域变体多样等特点&#xff0c;为语音合成技术带来独特挑战。ElevenLabs 提供的多语言、高保真…...

Veo生成模糊/断帧/色偏?立刻停用默认设置!20年视频架构师紧急发布的5项必改Veo 2K/4K硬核配置

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Veo 2K/4K视频生成质量崩塌的根源诊断 当Veo模型在2K或4K分辨率下输出视频时&#xff0c;高频细节严重丢失、运动伪影显著增强、纹理结构模糊化&#xff0c;这一现象并非单纯算力不足所致&#xff0c;而…...