JavaEE(系列8) -- 多线程案例(单例模式)
目录
1. 设计模式
2. 单例模式 -- 饿汉模式
3. 单例模式 -- 懒汉模式
4. 单例模式(懒汉模式-多线程)
1. 设计模式
什么是设计模式?
设计模式好比象棋中的 "棋谱". 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏.
软件开发中也有很多常见的 "问题场景". 针对这些问题场景, 大佬们总结出了一些固定的套路. 按照这个套路来实现代码, 也不会吃亏.
单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例.在特定场景下只被允许创建一个对象,比如在中国实行的是一夫一妻制.
2. 单例模式 -- 饿汉模式
class MySingleton {//static 该属性属于类的属性//JVM 每个类对象只有唯一一份,类对象里的这个成员自然也就是唯一一份.//instance是唯一实例private static MySingleton instance = new MySingleton();private MySingleton(){//禁止外部创建新的实例//将构造方法设置为private};public static MySingleton getInstance() {return instance;}public static void setInstance(MySingleton instance) {MySingleton.instance = instance;}
}
public class Singleton1 {public static void main(String[] args) {//1.此时s1 和 s2 是同一个对象MySingleton s1 = MySingleton.getInstance();MySingleton s2 = MySingleton.getInstance();System.out.println(s1 == s2);//2.我们要禁止这个new操作,把该类的构造方法用private修饰//Singleton.MySingleton s3 = new Singleton.MySingleton();}
}
上述代码就是单例模式中的饿汉模式
1.加载类的同时,创建实例对象.
2.同时将构造方法变为私有
理解:我吃完饭,我就把碗洗了
3. 单例模式 -- 懒汉模式
class MySingletonLazy{private static MySingletonLazy instance = null;public static MySingletonLazy getInstance(){if (instance == null){instance = new MySingletonLazy();}return instance;}private MySingletonLazy(){}
}
上述代码就是单例模式中的懒汉模式
1.加载类的时候,没有创建实例对象.而是写成一个静态方法,当需要创建对象的时候调用静态方法,创建对象.
2.同时将构造方法变为私有
理解:吃完饭,没有把碗洗了,而是我什么时候用,什么时候洗碗
4. 单例模式(懒汉模式-多线程)
思考:
上述两种模式,加入多线程是否是线程安全的?
答案: 饿汉模式安全,懒汉模式不安全
在多线程中,懒汉模式可能无法保证创建对象的唯一性。
如何解决由于懒汉模式(多线程)引起的线程的不安全呢?
答案: 加锁 保证判定操作和new操作是原子性的。
class MySingletonLazy2{volatile private static MySingletonLazy2 instance = null;public static MySingletonLazy2 getInstance(){synchronized (MySingletonLazy.class){//保证原子性if (instance == null){instance = new MySingletonLazy2();}}return instance;}
}
上述,我们对判断是创建对象这一块进行了加锁,从而保证了创建对象的原子性.
但是,如果这样,由于我们每次都要判断是否有了对象实例,就要不停地加锁解锁,这就是一个开销比较高的事情了.
如何解决频繁的加锁解锁这个过程呢?
答案:
加锁 / 解锁是一件开销比较高的事情. 而懒汉模式的线程不安全只是发生在首次创建实例的时候.
因此后续使用的时候, 不必再进行加锁了,那么我们就在加锁之前判断是否已经有实例.使用双重if进行判断 .代码如下:
class MySingletonLazy2{volatile private static MySingletonLazy2 instance = null;public static MySingletonLazy2 getInstance(){//外层的if,判定是否要加锁,如果对象已经有了,就没必要进行加锁,此时是线程安全的了,//加锁 / 解锁是一件开销比较高的事情. 而懒汉模式的线程不安全只是发生在首次创建实例的时候.//因此后续使用的时候, 不必再进行加锁了.if (instance == null){//解释:如果线程2执行到这里,发现对象还没创建,就会进行下一步,此时如果线程1正在创建对象,那么2就会进入堵塞状态,// 等待线程1创建玩对象,锁解除,那么线程2此时判断对象已经建立,此时就不会创建新的对象,此时就保证了线程之间的安全.synchronized (MySingletonLazy.class){//保证原子性if (instance == null){instance = new MySingletonLazy2();}}}return instance;}
}
//解释:如果线程2执行到第一个if里面,发现对象还没创建,就会进行下一步,此时如果线程1正在创建对象,那么2就会进入堵塞状态,
// 等待线程1创建玩对象,锁解除,那么线程2此时判断对象已经建立,此时就不会创建新的对象,此时就保证了线程之间的安全.这就是上述加了双重if的好处.
细心的读者还会发现,上述代码instance的修饰加上了volatile关键字,这一步为了避免“内存可见性”导致读取的instance出现偏差,于是补充上volatile,这也是优化的关键一步.
相关文章:

JavaEE(系列8) -- 多线程案例(单例模式)
目录 1. 设计模式 2. 单例模式 -- 饿汉模式 3. 单例模式 -- 懒汉模式 4. 单例模式(懒汉模式-多线程) 1. 设计模式 什么是设计模式? 设计模式好比象棋中的 "棋谱". 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路…...

深度剖析,如何从底层代码层面理解Selenium和Appium的关联
目录 前言: 一、Selenium和WebDriver 二、Appium和WebDriver 三、Selenium和Appium的底层关联 1. Selenium WebDriver提供底层的浏览器控制机制 2. 利用JSON Wire Protocol通信协议实现通讯机制 四、实例代码 总结: 前言: Selenium和…...

【Three.js】第一、二章 入门指南和基础知识
01.介绍 Three.js 非常庞大,你可以用它做无数的事情。 在第一章中,我们将学习所有基础知识,例如创建第一个场景、渲染、添加对象、选择正确的材料、添加纹理、为所有内容制作动画,甚至将其放到网上。有些人可能会觉得这部分有点…...

力扣第 104 场双周赛 2681. 英雄的力量
原题链接力扣 题目大意:我开始看成连续子段了,写了个递归程序....... 一个数组任选一个子序列,子序列的力量值最大值平方*最小值。求所有子序列的力量和。 分析过程:如序列长度为n,子序列总数为2的n次幂,…...
在linux上创建crypto_LUKS格式的块设备
要在Linux上创建一个块设备并将其格式化为 crypto_LUKS,可以按照以下步骤进行: 创建一个空白文件,作为块设备的基础。可以使用 dd 命令创建指定大小的文件,例如: dd if/dev/zero of/path/to/device bs1M count100这将创…...

76.建立一个主体样式第二部分
上节课的时候我们完成的页面是这个样子! ● 之后我们通过绝对定位来解决位置定位的问题 .header-container {width: 1200px;margin: 0 auto;position: absolute;left: 50%;top: 50%; }header {height: 100vh;background-color: orange;position: relative; }● 之…...

SQL删除重复的记录(只保留一条)-窗口函数row_number()
文章目录 一、关于mysql表中数据重复二、聚合函数min(id)not in二、窗口函数row_number()四、补充:常见的窗口函数 一、关于mysql表中数据重复 关于删除mysql表中重复数据问题,本文中给到两种办法:聚合函数、窗口函数row_number()的方法。 (注…...
CF1660D Maximum Product Strikes Back 题解
CF1660D Maximum Product Strikes Back 题解 题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 思路点拨(分类题)缩小研究对象范围除0的分析加上0的分析 代码实现小方法陈述 题目描述 你有一个长度为 n n n 的数组,每一个元素都在 …...
基于CSSOM的暗链检测技术实现方案
什么是暗链 大部分的开源代码在实现暗链检测的时候都是直接判断页面里面有没有敏感词,如果有,就认为该链接为暗链。这种做法其实是有误的。 违规链接应该分为:外链、内链、死链和暗链。而暗链除了违规,还应该具备“暗”这个看不见的特征。 暗链的特征 其实“暗链”就是看…...
MySQL db、tables_priv、columns_priv和procs_priv权限表
在 MySQL 数据库中,权限表除了 user 表外,还有 db 表、tables_priv 表、columns_priv 表和 procs_priv 表。在《MySQL user权限表详解》中我们讲解了 MySQL 的 user 表,下面主要介绍其它几种权限表。 db表 db 表比较常用,是 MyS…...

JavaWeb-JSP的学习
JSP 今日目标: 理解 JSP 及 JSP 原理能在 JSP中使用 EL表达式 和 JSTL标签理解 MVC模式 和 三层架构能完成品牌数据的增删改查功能 1、JSP 概述 JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的网页技术…...

力扣sql中等篇练习(二十三)
力扣sql中等篇练习(二十三) 1 统计实验的数量 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 有可能数据本身就不全,就需要自行创建临时表 WITH T as (SELECT Android p1,Reading e1UNIONSELECT Android p1,Sports e1UNIONSELECT Android p1,Prog…...
C语言算法之查找
一.查找相关概念 这一部分解释数据结构里面查找的相关基础概念: 查找:在数据集合中寻找满足某种条件的数据元素的过程。查找表:用于查找的数据集合关键字:数据元素中唯一标识该元素的某个数据项的值静态查找表:静态查…...

肝一肝设计模式【九】-- 享元模式
系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 肝一肝设计模式【六】-- 装饰器模式 传送门 肝…...
自动化测试的十大雷区【刚入门必看】
虽然从自己的错误中学习也不错,但从别人的错误中学习总是更好的。 作为一个自动化测试人员,分享常见的容易犯的10个错误,可以从中吸取教训,引以为鉴。 一、必要时才自动化 新人小王接到为Web应用程序自动化测试脚本的任务时&…...
【Android源码篇】用grep搜索源码内容关键词
前言 选项: • -w:只匹配整个单词,不会部分匹配 • -r:递归搜索 • -n:显示行号 • -i:忽略字符大小写 • -I(大写i):忽略二进制文件 • -I:忽略文件内容&am…...

腾讯云轻量应用服务器卡死怎么连接?
腾讯云轻量云服务器卡死怎么解决?使用腾讯云自带的VNC登录连接轻量服务器,或使用腾讯云OrcaTerm一键免密登录轻量实例。如果是确定数据没问题,也可以使用控制台自带的重启实例。 腾讯云轻量应用服务器参考:https://curl.qcloud.co…...

Charles安装及抓取APP接口
一、Charles使用 Charles是一款代理服务器,通过过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的,能够在Windows,Mac,…...

Linux开发工具:yum和vim的使用
目录 一. Linux下的软件 1.1 软件安装的三种方法 1.2 采用yum安装软件 1.3 yum源的问题 二. vim开发工具的使用 2.1 vim的三种基本模式 2.2 命令模式下vim的常用指令 2.2.1 定位相关指令 2.2.2 光标移动相关指令 2.2.3 插入相关指令 2.2.4 复制粘贴相关指令 2.2.5 替…...

Java基础重温巩固
方法 方法与方法之间是平级关系,不能嵌套return表示结束当前方法 基本数据类型和引用数据类型 基本数据类型:数据存储在自己的空间中 引用数据类型:数据存储在其他空间中,自己空间存储的是地址值 值传递 传递基本数据类型时&…...
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…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...