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

单例模式的相关知识

饿汉模式

package Thread;
class Singleton{private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}private Singleton(){}
}public class demo1 {public static void main(String[] args) {Singleton S1 =Singleton.getInstance();Singleton S2 =Singleton.getInstance();System.out.println(S1==S2);
//        Singleton S3 =new Singleton();}
}

在这里插入图片描述

所谓的单例模式,就是指一个类的对象只能创建一个,上述代码中,Singleton这个类中,有一个static修饰的对象,这个对象就是一个类对象,具有类属性,由于类对象只有一个,也就是说,每个类的类对象是单例的,所以,类对象 的属性(static),也就是单例的了,这个对象创建的时间是在Singleton第一次被JVM使用的时候.
有了这个对象后,不能允许在类外面创建对象,因此,我们就需要将类的构造方法改为private修饰,这样,只要在类外面尝试用new来创建对象,而不是调用get方法,系统就会报错.
在这里插入图片描述
在这里插入图片描述
但是,这样并不保证就一定不可以在类外面创建多个不同的对象,"反射"这个操作就可以做到,但是做这个操作需要谨慎,滥用反射,会带来极大的风险,因此,我们并不推荐使用这个方法.

懒汉模式

package Thread;
class Singletonlazy{private static Singletonlazy instance = null;public static Singletonlazy getInstance(){if(instance==null){instance = new Singletonlazy();}return instance;}private Singletonlazy(){}
}
public class demo2 {public static void main(String[] args) {Singletonlazy S1 = Singletonlazy.getInstance();Singletonlazy S2 = Singletonlazy.getInstance();System.out.println(S1==S2);}
}

在这里插入图片描述
懒汉模式与饿汉模式最主要的区别就是,类对象创建的时间不同,懒汉模式并不是Singletonlazy类在第一次被加载的时候创建的,而是在get方法第一次被调用的时候才会创建

线程安全问题

饿汉模式的get方法
在这里插入图片描述
懒汉模式的get方法
在这里插入图片描述
从上述代码中可以看出,饿汉模式下的get方法只涉及到读取操作,并没有进行对变量的修改,而懒汉模式下的get方法,涉及对对象引用的修改,而且是存在if的判断条件,说明该修改操作不是一个原子级别的,综上所述,懒汉模式存在严重的线程安全问题,会导致出现两个线程都new出一个新的对象的情况,虽然系统最后会对后面new出来的对象进行清除,但是,创建两个对象所花费的资源和时间确是巨大的损失,所以,为了避免这样的损失,我们需要对该方法进行加锁

加锁

为了解决懒汉模式下的线程安全问题,我们尝试对get方法的修改操作进行加锁,注意,这里进行加锁的范围需要包含if的条件判断和修改的具体操作,需要将这两个步骤所在一起,才能解决线程安全问题
但是我们也需要注意,加锁也不能滥用,因为加锁也是很消耗资源和时间,能不加锁的情况就不要加锁,否则,会对代码的运行效率造成极大的影响
就比如这里我们锁需要加锁的代码,只有第一次调用的时候,才会对对象的引用进行修改,后续再次调用该方法的时候,也只是如饿汉模式下的方法一样,只是进行读操作,所以,我们要求,在加锁的时候,我们也要做到,只有在第一次具有线程安全问题的情况下,我们才进行加锁,其余情况下,就避免加锁带来 的额外的负担,那我们需要怎么做呢
再加一个if判断
在这里插入图片描述
先判断是否需要加锁,再判断是否真的需要加锁
第一个if是为了判断是否需要加锁,第二个if是判断是否需要创建新的对象
因为这里是多线程,在加锁的时候,可能涉及到阻塞的情况,阻塞时间的长短我们也不知道,因此,可能存在由于两个if之间的时间相隔过久,在这段时间里,可能会有其他线程将对象给修改掉的情况
但是这里的第二个线程一定能读取到第一个线程修改的值吗,这里就涉及到之前章节讲到的内存可见性

内存可见性

为了避免编译器优化导致的系统bug,我们需要给instance这个变量加上一个volatile,来确保代码的准确性
在这里插入图片描述

指令重排序

这里除了可能会有内存可见性的问题之外,也可能会有指令重排序导致的问题出现,什么是指令重排序呢,举个例子
假如我们完成一个工作的步骤是123,经过编译器优化之后,步骤就变为了132,甚至321.这样的优化的好处和内存可见性的优化一样,都可以大幅度提高程序运行的效率,但是这如果只是在单线程的情况下还好,但是在多线程的情况下了,就有很大可能会引发线程安全问题,再举个例子
我们想要new一个instance对象出来,需要分为三个步骤
1.创建出内存空间,得到内存地址
2.再空间上调用构造方法,对对象进行初始化
3.把内存地址幅值给Instance引用
如果是单线程的情况下,23可以互调,不会有太大的影响
但是如果发生在多线程的情况下,此时还没来得及给instance初始化,就调度给其他线程了,第二个线程在执行的时候,判定instance!=null,于是就把instance给返回出去了,并且后续可能还会涉及掉用instance中的方法,而instance 现在只是一具空壳,并没有被初始化,这就可能会造成严重的问题
那么我们怎么解决这个问题呢,这里我们也可以利用volatile来解决问题.
给instance加上volatile之后,就不会产生指令重排序了

相关文章:

单例模式的相关知识

饿汉模式 package Thread; class Singleton{private static Singleton instance new Singleton();public static Singleton getInstance(){return instance;}private Singleton(){} }public class demo1 {public static void main(String[] args) {Singleton S1 Singleton.ge…...

vue问题相关记录

1. vue的 nextTick的原理 首先vue实现响应式并不是数据发生变化后dom立即更新,而是按照一定的策略 异步执行dom更新的。 vue在修改数据后,试图不会立即进行更新,而是要等同一事件循环机制内所有数据变化完成之后,在统一更新 next…...

skywalking服务部署

一、前言 Apache SkyWalking 是一个开源的分布式跟踪、监控和诊断系统,旨在帮助用户监控和诊断分布式应用程序、微服务架构和云原生应用的性能和健康状况。它提供了可视化的分析工具,帮助开发人员和运维团队深入了解应用程序的性能、调用链和异常情况 …...

【uni-app】压缩图片并添加水印

总体思路 dom 结点 这里的 cvHeight 和 cvWidth 初始时要设置为你后续需要压缩后的最大宽高。假设我们在图片上传后图片最大为 350 * 350 <u-upload :fileList"baseInfoFormData.entrustFileList" afterRead"afterFileRead" multiple></u-uploa…...

《每天十分钟》-红宝书第4版-变量、作用域与内存

最近有点忙&#xff0c;好长时间没抄经了&#xff0c;今天继续&#xff0c;之前语言基础相对简单&#xff0c;跳过一部分操作符。 变量 js 的变量是特殊的松散类型&#xff0c;由于没有规则定义变量必须包含什么数据类型&#xff0c;变量的值和数据类型在脚本生命期内可以改变…...

NFTScan | 08.21~08.27 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。周期&#xff1a;2023.08.21~ 2023.08.27 NFT Hot News 01/ NFT 品牌体验平台 Recur 将于 11 月 16 日彻底关闭&#xff0c;此前曾获 5000 万美元融资 8 月 21 日&#xff0c;NFT 品牌体验平台 Recur 在 X…...

【Java 中级】一文精通 Spring MVC - 数据验证(七)

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…...

css奇数偶数选择器

前端项目开发中&#xff0c;需要根据行数的奇数和偶数的不同&#xff0c;设置不同的颜色显示&#xff0c;以在视觉上给用户以良好的浏览体验&#xff0c;这里就需要使用css奇数偶数选择器。 主要用的&#xff1a;:nth-of-type或者:nth-child。 方式一:nth-child div:nth-chi…...

【算法】双指针求解盛最多水的容器

Problem: 11. 盛最多水的容器 文章目录 题目解析算法原理讲解复杂度Code 题目解析 首先我们来解析一下本题 题目中说到&#xff0c;要找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 那我们现在来看最外侧的两根&#xff0c;一个高度为8&#…...

浅析SAS协议:设备接入与探测

文章目录 SAS设备初始化OOB信号SAS设备间OOB交互场景一&#xff1a;SAS设备两边同时发送SAS COMINIT信号场景二&#xff1a;SAS设备A先发送COMINIT信号场景三&#xff1a;SAS设备B错过COMINIT信号 SAS与SATA设备间OOB交互场景一&#xff1a;SATA设备未响应COMSAS信号场景二&…...

RISC-V IOPMP实际用例-Andes SoC‘s Rapid-k模型

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。...

【高阶数据结构】哈希表详解

文章目录 前言1. 哈希的概念2. 哈希冲突3. 哈希函数3.1 直接定址法3.2 除留余数法--(常用)3.3 平方取中法--(了解)3.4 折叠法--(了解)3.5 随机数法--(了解)3.6 数学分析法--(了解) 4. 哈希冲突的解决方法及不同方法对应的哈希表实现4.1 闭散列&#xff08;开放定址法&#xff0…...

C#与西门子PLC1500的ModbusTcp服务器通信4--搭建ModbusTcp客户端

1、客户端选择 客户端可以是一个程序或一个设备&#xff0c;这里我以C#WINFORM程序来实现客户机与PLC的Modbustcp服务器通信&#xff0c;开发环境是VS2019&#xff0c;.NET Framework版本是4.7.2 2、创建winform程序 3、引入Nmodbus4协议 找到项目&#xff0c;找到引用&…...

性能调优篇 二、Jvm监控及诊断工具-命令行篇

目录 一、概述1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序&#xff08;掌握&#xff09;1、是什么&#xff1f;2、测试3、基本语法 三、jstat&#xff1a;查看jvm统计信息&#xff08;掌握&#xff09;1、是什么&#xff1f;2、基本语法3、补充 四、jinfo&am…...

Fooocus启动时modules报错的解决方法

原理&#xff1a;是由于其他程序的安装导致modules的版本不对&#xff0c;先卸载现有版本&#xff0c;再运行run.bat让其自动安装响应的modules版本。 1、cmd运行windows dos终端。 2、将Fooocus_win64_1-1-1035文件夹备份&#xff0c;rename为Fooocus_win64_1-1-1035backup文…...

RSA私钥解密操作

RSA私钥解密操作 一、背景二、操作三、常见问题3.1 invalid key format3.2 解密的数据太长3.3 Decryption error 一、背景 项目数据库中存放的敏感字段已使用rsa加密的方式&#xff0c;将内容加密成密文存放, 现在需要在使用的时候&#xff0c;使用私钥进行解密。 二、操作 …...

数据库基本知识

基本概念 数据 描述事物的符号记录称为数据&#xff0c;数字&#xff0c;文字&#xff0c;图形&#xff0c;图像&#xff0c;声音&#xff0c;档案记录等都是数据 数据是以“记录”的形式按照统一的格式进行存储的&#xff0c;而不是杂乱无章的 相同格式和类型的数据统一存…...

使用Redis统计网站的UV/DAU

HyperLogLog/BitMap 统计UV、DAU需要用到Redis的高级数据类型 M public class RedisKeyUtil {private static final String PREFIX_UV "uv";private static final String PREFIX_DAU "dau";// a single days UVpublic static String getUVKey(String …...

【python】报错:ImportError: DLL load failed: 找不到指定的模块 的详细解决办法

原因&#xff1a;安装的包与python版本不一致 解决方法&#xff1a; 查看python版本&#xff1a; #python / #python -V Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] on win32只查看python第三方模块&#xff08;库、包&…...

SemrushBot蜘蛛爬虫屏蔽方式

查看访问日志时候发现有SemrushBot爬虫 屏蔽方法&#xff1a; 使用robots.txt文件是一种标准的协议,用于告诉搜索引擎哪些页面可以和不能被爬取,如想禁止Googlebot爬取整个网站的话,可以在该文件中添加以下内容: User-agent: Googlebot Disallow: / 对于遵循robots协议的蜘蛛…...

6 ssh面密登录

1. 首先进入自己的家目录&#xff0c;执行命令 [atguiguhadoop102 .ssh]$ ssh-keygen -t rsa然后敲&#xff08;三个回车&#xff09;&#xff0c;就会生成两个文件id_rsa&#xff08;私钥&#xff09;、id_rsa.pub&#xff08;公钥&#xff09; 2. 将公钥拷贝到要免密登录的…...

基于微信小程序的汽车租赁系统的设计与实现ljx7y

汽车租赁系统&#xff0c;主要包括管理员、用户二个权限角色&#xff0c;对于用户角色不同&#xff0c;所使用的功能模块相应不同。本文从管理员、用户的功能要求出发&#xff0c;汽车租赁系统系统中的功能模块主要是实现管理员后端&#xff1b;首页、个人中心、汽车品牌管理、…...

优化学习体验的在线考试系统

随着互联网的发展&#xff0c;在线教育逐渐成为学习的主要方式之一。在线考试系统作为在线教育的重要组成部分&#xff0c;对于学习者提供了更为便捷和灵活的学习方式。但是&#xff0c;如何优化学习体验&#xff0c;提高学习效果&#xff0c;仍然是在线考试系统需要解决的问题…...

1267. 统计参与通信的服务器

题目描述&#xff1a; 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能…...

【考研数学】矩阵、向量与线性方程组解的关系梳理与讨论

文章目录 引言一、回顾二、梳理齐次线性方程组非齐次线性方程组 写在最后 引言 两个原因让我想写这篇文章&#xff0c;一是做矩阵题目的时候就发现这三货经常绑在一起&#xff0c;让人想去探寻其中奥秘&#xff1b;另一就是今天学了向量组的秩&#xff0c;让我想起来了之前遗留…...

打造个人的NAS云存储-通过Nextcloud搭建私有云盘实现公网远程访问

文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文件共享服…...

FFI绕过disable_functions

文章目录 FFI绕过disable_functions[RCTF 2019]NextphpPHP7.4 FFI参考 FFI绕过disable_functions [RCTF 2019]Nextphp 首先来看这道题目 index.php <?php if (isset($_GET[a])) {eval($_GET[a]); } else {show_source(__FILE__); }查看一下phpinfo 发现过滤了很多函数&…...

53 个 CSS 特效 2

53 个 CSS 特效 2 这里是第 17 到 32 个&#xff0c;跟上一部分比起来多了两个稍微大一点的首页布局&#xff0c;上篇&#xff1a;53 个 CSS 特效 1&#xff0c;依旧&#xff0c;预览地址在 http://www.goldenaarcher.com/html-css-js-proj/&#xff0c;git 地址&#xff1a; …...

ubuntu学习(六)----文件编程实现cp指令

1 思路 Linux要想复制一份文件通常指令为&#xff1a; cp src.c des.c 其中src.c为源文件&#xff0c;des.c为目标文件。 要想通过文件编程实现cp效果&#xff0c;思路如下 1 首先打开源文件 src.c 2 读src到buf 3 创建des.c 4 将buf写入到des.c 5 close两个文件 2 实现 vi …...

wireshark过滤器的使用

目录 wiresharkwireshark的基本使用wireshark过滤器的区别 抓包案例 wireshark wireshark的基本使用 抓包采用 wireshark&#xff0c;提取特征时&#xff0c;要对 session 进行过滤&#xff0c;找到关键的stream&#xff0c;这里总结了 wireshark 过滤的基本语法&#xff0c;…...