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

【JavaEE】多线程进阶(一)饿汉模式和懒汉模式

多线程进阶(一)

文章目录

  • 多线程进阶(一)
    • 单例模式
      • 饿汉模式
      • 懒汉模式

本篇主要引入多线程进阶的单例模式,为后面的大冰山做铺垫

代码案例介绍

单例模式

非常经典的设计模式

啥是设计模式

设计模式好比象棋中的 “棋谱”. 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏.

软件开发中也有很多常见的 “问题场景”. 针对这些问题场景, 大佬们总结出了一些固定的套路. 按照这个套路来实现代码, 也不会吃亏.

单例 -> 单个实例(对象)

在有些场景下,希望有的类,只能有一个对象,不能有多个!在这样的场景下就可以使用单例模式了。

举个有意思的例子就是,你只能娶一个老婆,不过你可以生很多娃🥵🥵🥵,娃就不一定是单例的


在代码中,有很多用于管理数据的对象,就应该是”单例“的,例如mysql JDBC DataSource(描述mysql服务器的位置)

那么这里有个问题:

单例这个事情,还需要设计模式吗?

当我们写代码的时候,只给这个类new一次对象,不去new多次不就行了?

实际上,设计模式是非常必要的,这其实上是属于设计模式,这完全就是取决于程序员的编程素养。

不过俗话说,宁可相信世界上有鬼,也不能相信人的这张破嘴!人是非常不靠谱的。

这样的思想方法在很多地方都会涉及到:

  1. final
  2. intreface
  3. @Override
  4. throws

于是此时就需要让编译器帮我们做监督,确保这个对象不会出现多个new(出现多个的时候就直接编译报错)

饿汉模式

类加载的同时, 创建实例.

// 饿汉模式
class Singleton{private static Singleton instance = new Singleton();//通过这个方法来获取到刚才的实例//后续如果想使用这个类的实例,都通过 getInstance 方法来获取public static Singleton getInstance(){return instance;}//把构造方法设置为私有,此时类外面的其他代码,就无法 new 出这个类的对象private Singleton(){}
}public class Demo21 {public static void main(String[] args) {//此外又有一个实例,这就不是单例了//Singleton s1 = new Singleton();Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2);//true}
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

懒汉模式

相比于饿汉模式,他就比较从容,在第一次使用的时候,再去创建实例

//懒汉模式class SingletonLazy{private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance(){if (instance == null) {if (instance == null) {instance = new SingletonLazy();}}return instance;}private SingletonLazy(){}
}public class Demo22 {public static void main(String[] args) {//此外又有一个实例,这就不是单例了//Singleton s1 = new Singleton();SingletonLazy s1 = SingletonLazy.getInstance();SingletonLazy s2 = SingletonLazy.getInstance();System.out.println(s1 == s2);//true}
}

在这里插入图片描述

我们举个例子:

文本编辑器

记事本

需要打开一个非常大的文件

  1. 先把所有的内容都加载到内存中,然后再显示内容(加载过程会很慢)
  2. 只加载一小部分数据到内存,立即显示内容,随着用户翻页,再动态加载其他内容(懒汉模式

那么这里我们抛出一个问题:

以上两种模式的写法,是否是线程安全的?(如果有多个线程,同时调用getInstance,是否会出问题?)

如果多个线程,同时修改同一个变量,此时就可能出现线程安全问题

如果多个线程,同时读取同一个变量,这个时候就没什么事情,不会有安全问题

那么我们看看饿汉模式的代码:

public static Singleton getInstance(){return instance;}

饿汉模式下的getInstance只是进行读取,不是修改,那么他也就没有线程安全的问题了~

那我们看看懒汉模式的代码:

if(instance == null){instance = new SingletonLazy();
}
return instance;

它既会读取,又会修改,就可能存在问题~

在这里插入图片描述

那么我们怎么保证懒汉模式是线程安全的呢?

类似于下面这种改法吗?

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

当然不是,我们要明确一个事情,就是:锁,不是加了就安全

加的位置对不对,才是关键

  1. 锁的{}的范围,是合理的,能够把需要作为整体的每个部分都囊括进去
  2. 锁的对象,也得是能够起到合理的锁竞争的效果

这样才是真正的加锁

所以修改如下:

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

ifnew合并成一个整体,此时的线程安全就迎刃而解了

不过一旦这么写的话,后续每次调用getInstance,都需要先加锁了

不过这种操作属实是画蛇添足了,加锁是一个开销很大的操作,加锁就可能会涉及到锁冲突 一冲突就会引起阻塞等待。

还有就是:一旦某个代码涉及到 加锁,那么基本上就可以宣告这个代码和“高性能”无缘了~

但是实际上,懒汉模式,线程安全的问题,只是出现在最开始的时候(对象还没开始new呢)

一旦对象new出来了,后续多线程调用getInstance,就只有读操作,就不会线程不安全了~

那么这里抛出一个问题:

是否有什么办法可以让代码线程安全,又不会对执行效率产生太多影响呢?

欲知后事如何,敬请期待下一篇博客~

主要是我临时有事,等明天写完再更😥😥😥😥😥😥😥😥😥

在这里插入图片描述

相关文章:

【JavaEE】多线程进阶(一)饿汉模式和懒汉模式

多线程进阶(一) 文章目录 多线程进阶(一)单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式,为后面的大冰山做铺垫 代码案例介绍 单例模式 非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”…...

C++树详解

树 树的定义 树(Tree)是n(n≥0)个结点的有限集。n0时称为空树。在任意一颗非空树中:①有且仅有一个特定的称为根(Root)的结点;②当n>1时,其余结点可分为m&#xff08…...

支付环境安全漏洞介绍

1、平台支付逻辑全流程分析 2、平台支付漏洞如何利用?买东西还送钱? 3、BURP抓包分析修改支付金额,伪造交易状态? 4、修改购物车参数实现底价购买商品 5、SRC、CTF、HW项目月入10W副业之路 6、如何构建最适合自己的网安学习路线 1…...

抄写Linux源码(Day16:内存管理)

回忆我们需要做的事情: 为了支持 shell 程序的执行,我们需要提供: 1.缺页中断(不理解为什么要这个东西,只是闪客说需要,后边再说) 2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的,所以需要这两个东…...

Cookie和Session详解以及结合生成登录效果

目录 引言 1.Cookie中的数据从哪来数据长啥样? 2.Cookie有什么作用? 3.cookie与session的工作关联? 4.Cookie到哪去? 5.Cookie如何存? 6.Session 7.Cookie与Session的关联与区别 8.通过代码理解 8.1 相关代码 8.2…...

Spring基础以及核心概念(IoC和DIQ)

1.Spring是什么 Spring是包含了众多工具方法的IoC容器 2.loC(Inversion of Control )是什么 IoC:控制反转,Spring是一个控制反转容器(控制反转对象的生命周期) Spring是一个loC容器,我们之前学过的List/Map就是数据存储的容器,to…...

《C和指针》笔记32:多维数组初始化

文章目录 使用括号进行初始化初始化省略维度 使用括号进行初始化 我们可以给数组赋值一个长长的列表: int matrix[2][3] { 100, 101, 102, 110, 111, 112 };它等价于 matrix[0][0]100; matrix[0][1]101; matrix[0][2]102; matrix[1][0]110; matrix[1][1]111; ma…...

零食食品经营小程序商城的作用是什么

零食几乎可以涵盖每个年龄阶段,同时又是市场中常见的零售批发商品,在多个场景中都有销售/购买属性,对消费者来说,购买零食的渠道多种多样,无论线下还是线上,都可随心而购。 庞大市场升级促进下&#xff0c…...

Java泛型--什么是泛型?

https://www.bilibili.com/video/BV1xJ411n77R?p5&vd_sourcebb1fced25254581cf052adea5e87a1ff 1.泛型类、接口 1.1.泛型类 泛型类的定义 class 类名称 <泛型标识, 泛型标识, ...> {private 泛型标识 变量名;...... }常用的泛型标识&#xff1a;T、E、K、V jav…...

LabVIEW工业虚拟仪器的标准化实施

LabVIEW工业虚拟仪器的标准化实施 创建计算机化的测试和测量系统&#xff0c;从计算机桌面控制外部测量硬件设备&#xff0c;以及在计算机屏幕上显示的类似仪器的面板上查看来自外部设备的测试或测量数据&#xff0c;所有这些都需要虚拟仪器系统软件。该软件允许用户执行所有这…...

JavaScript系列从入门到精通系列第十七篇:JavaScript中的全局作用域

文章目录 前言 1&#xff1a;什么叫作用域 一&#xff1a;全局作用域 1&#xff1a;全局变量的声明 2&#xff1a;变量声明和使用的顺序 3&#xff1a;方法声明和使用的顺序 前言 1&#xff1a;什么叫作用域 可以起作用的范围 function fun(){var a 1; } fun();consol…...

汇编指令集合

...

TinyWebServer整体流程

从main主函数开始&#xff1a; 一、定义MySQL数据库的账号、密码和用到的数据库名称。 二、调用Config获得服务器初始化属性 在这一步确定触发模式端口等信息。 三、创建服务器实例对象 设置根目录、开辟存放http连接对象的空间&#xff0c;开辟定时器空间。 四、利用Confi…...

【Java项目推荐之黑马头条】自媒体文章实现异步上下架(使用Kafka中间件实现)

自媒体文章上下架功能完成 需求分析 流程说明 接口定义 说明接口路径/api/v1/news/down_or_up请求方式POST参数DTO响应结果ResponseResult DTO Data public class WmNewsDto {private Integer id;/*** 是否上架 0 下架 1 上架*/private Short enable;}ResponseResult 自媒…...

自学(黑客)技术方法————网络安全

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…...

python+playwright 学习-84 Response 接口返回对象

Response 是获取接口响应对象,根据Response 对象可以获取响应的状态码,响应头部,响应正文等内容。 Response 相关操作方法 all_headers 所有响应HTTP标头, 返回Dict 类型 response.all_headers()body 获取 bytes 类型body内容 response.body()json 返回响应主体的 JS…...

GCN详解

a ⃗ \vec{a} a 向量 a ‾ \overline{a} a 平均值 a ‾ \underline{a} a​下横线 a ^ \widehat{a} a (线性回归&#xff0c;直线方程) y尖 a ~ \widetilde{a} a a ˙ \dot{a} a˙ 一阶导数 a \ddot{a} a 二阶导数 H(l)表示l层的节点的特征 W(l)表示l层的参数 D ~ \widet…...

总结二:linux面经

文章目录 1、 Linux中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数。2、文件权限怎么修改&#xff1f;3、说说常用的Linux命令&#xff1f;4、说说如何以root权限运行某个程序&#xff1f;5、 说说软链接和硬链接的区别&#xff1f;6、说说静态库和动态…...

12、【Qlib】【主要组件】Qlib Recorder:实验管理

11、【Qlib】【主要组件】Qlib Recorder:实验管理 简介Qlib RecorderExperiment ManagerExperimentRecorderRecord Template简介 Qlib包含一个名为QlibRecorder的实验管理系统,旨在帮助用户以高效的方式处理实验并分析结果。 该系统有三个组件: 实验管理器(ExperimentMan…...

三一充填泵:煤矿矸石无害化充填,煤炭绿色高效开采的破局利器

富煤贫油少气是我国的能源禀赋特征&#xff0c;决定了我国以煤炭为主的能源结构&#xff0c;煤炭为国民经济发展提供了重要的基础。煤炭开采过程会对土地、地下水、空气等环境造成较大的污染&#xff0c;但大宗固废煤矸石无害化充填的技术手段可以有效改善这样的情况&#xff0…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...