单例模式(饿汉式单例 VS 懒汉式单例)

所谓的单例模式就是保证某个类在程序中只有一个对象

一、如何控制只产生一个对象?

1.构造方法私有化(保证对象的产生个数)

        创建类的对象,要通过构造方法产生对象

       构造方法若是public权限,对于类的外部,可以随意创建对象,无法控制对象个数

      构造方法私有化,这样类的外部就彻底无法产生对象,一个对象都没有。

2.单例类的内部提供这个唯一的对象(static)

        构造方法私有化后,对于类的外部而言就一个对象都没有了。因此要在这个类的内部构造出这个唯一的对象,只调用一次构造方法即可(这个单例对象不能是类的成员属性,因为成员变量必须通过对象来访问,但是类的外部根本无法产生对象,(矛盾),因此这个对象必须使用static关键字修饰,静态变量,不依赖类的对象

3.单例类提供返回这个唯一对象的静态方法供外部使用

二、饿汉式单例

饿汉式单例模式是天然的线程安全的。类加载时就创建了这个唯一的对象!!!

/*** 饿汉式单例(类加载就产生这个唯一的对象,也不管外部是否调用该对象)。饥不择食,这个类一加载就把惟一的这个对象产生了,* 我也不管外部到底用不用这个对象,只要这个类加载到JVM,唯一对象就会产生**/
public class SingleTon {// 惟一的这一个对象private static SingleTon singleTon = new SingleTon();private SingleTon() {}// 调用此方法时,singleTon对象已经产生过了,多线程场景下取回的是同一个单例对象public static SingleTon getSingleton() {return singleTon;}
}

三、懒汉式单例

懒汉式单例:只有第一次调用getSingleTon(),表示外部需要获取这个单例对象时才产生对象

public class LazySingleTon {private static LazySingleTon singleTon ;private LazySingleTon(){}public LazySingleTon getSingleTon(){if (singleTon == null){singleTon = new LazySingleTon();}return singleTon;}
}

多线程场景下会产生线程安全问题(不能确保只有一个对象产生) 

在这个场景下,三个线程并发调用get方法,此时三个 线程看到的singleTon 都为null,因此,每个线程都创建了一个对象!!

四、解决懒汉式单例的线程安全问题

1.静态方法上加锁

    public synchronized static LazySingleTon getSingleTon(){if (singleTon == null){singleTon = new LazySingleTon();}return singleTon;}

在方法上上锁,表示同一时间只有一个线程能进入此方法(其他线程想要进入此方法都等待获取锁成功的线程释放锁)。此时,getSingleTon()的内部都是单线程操作(锁的粒度太粗)。

2.double-check(双重加锁)

    private volatile static LazySingleTon singleTon ;private LazySingleTon(){}public  static LazySingleTon getSingleTon(){if (singleTon == null){synchronized (LazySingleTon.class){if (singleTon == null){singleTon = new LazySingleTon();}}}return singleTon;}

volatile的作用:内存屏障,可见性

此时有t1,t2,t3三个线程,t1首先获取到了锁,开始执行new操作,虽然还没完全结束,但此时的singleTon != null,对于刚开始执行代码的t2,t3来说,它们看到singleTon != null 直接返回了,但是返回后的单例对象是一个尚未完全初始化的对象

此时采用volatile关键字修饰单例对象,new操作有着一堵墙,其它线程要能执行到return语句,JVM一定保证了new操作完全结束了,之后才会执行return语句

 double-check:防止其他线程恢复执行后多次创建单例对象

当t1先进入同步代码块后,t2,t3卡在获取所得位置,

t1产生对象后释放锁,

t2,t3还是从获取锁的位置继续执行,在他们的工作内存中,singleTon == null 

t2,t3就会再次new对象。

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

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

相关文章

JAR will be empty - no content was marked for inclusion!

现象 在对自建pom依赖组件打包时&#xff0c;出现JAR will be empty - no content was marked for inclusion!错误。 方案 在pom中怎么加packaging标签内容为pom&#xff0c;标识只打包pom文件 <?xml version"1.0" encoding"UTF-8"?> ...<grou…

科技互联网领域,怎样才算突破性创新?

在科技互联网领域&#xff0c;一个突破性的创新应该具备以下特征&#xff1a; 革命性&#xff1a;突破性创新应该能够彻底改变行业或市场&#xff0c;引起根本性的变革。前瞻性&#xff1a;突破性创新应该有前瞻性&#xff0c;能够在未来产生重大影响。这意味着创新应该不仅考…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)十二:通用详情组件封装实现

一、本章内容 本章实现通用详情组件,自动识别实体配置信息,并自动生成对应组件,填充组件数据,并完成数据自动加载等过程。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 3.1 B站视频地址࿱

对比学习与simclr详解

对比学习&#xff08;Contrastive Learning&#xff09;是一种机器学习方法&#xff0c;旨在通过比较数据样本之间的相似性和差异性来学习有用的表示&#xff08;特征&#xff09;。其核心思想是通过将相似的样本映射到相邻的位置&#xff0c;将不相似的样本映射到远离的位置&a…

微信小程序——简易复制文本

在微信小程序中&#xff0c;可以使用wx.setClipboardData()方法来实现复制文本内容的功能。以下是一个示例代码&#xff1a; // 点击按钮触发复制事件 copyText: function() {var that this;wx.setClipboardData({data: 要复制的文本内容,success: function(res) {wx.showToa…

ARM指令集

CPU是计算机的中央处理器&#xff0c;负责执行组成计算机程序的指令。为此&#xff0c;CPU必须能够解释机器码即计算机程序的最低级别表示形式&#xff0c;以让CPU可以直接执行。机器码是一系列的二进制指令&#xff0c;每个指令都代表CPU可以执行的特定操作。指令由一系列1和0…

微信小程序onReachBottom事件使用

在微信小程序中&#xff0c;onReachBottom事件用于监听页面滚动到页面底部的时候触发的事件。当用户滑动页面到底部时&#xff0c;可以通过监听该事件来执行相应的操作。 要使用onReachBottom事件&#xff0c;需要在对应的页面或组件中定义一个函数&#xff0c;并在Page或Comp…

vue3 将 HTML 网页内容生成为 PDF 文件

使用 html2pdf.js 实现 npmjs 地址&#xff1a;html2pdf.js github 仓库地址&#xff1a;html2pdf.js 使用 html2pdf.js 的方法非常简单&#xff0c;只需要能获取到要生成 PDF 的 HTML 元素即可 安装 npm i html2pdf.js引入 先在需要使用导出的页面引入 import html2pdf fr…

操作系统 --- 计算机系统引论

&#xff08;一&#xff09;操作系统的目的和作用 概念&#xff08;定义&#xff09; 操作系统 &#xff08; Operating System &#xff0c; OS &#xff09;是指控制和 管理 整个计算机系统的 硬件和软件 资源&#xff0c;并合理地组织调度计算机的工作和资源的分配&#…

数据分析面试题(2023.09.08)

数据分析流程 总体分为四层&#xff1a;需求层、数据层、分析层和结论层 一、统计学问题 1、贝叶斯公式复述并解释应用场景 公式&#xff1a;P(A|B) P(B|A)*P(A) / P(B)应用场景&#xff1a;如搜索query纠错&#xff0c;设A为正确的词&#xff0c;B为输入的词&#xff0c;那…

vue-elementPlus自动按需导入和主题定制

elementPlus自动按需导入 装包 -> 配置 1. 装包&#xff08;主包和两个插件包&#xff09; $ npm install element-plus --save npm install -D unplugin-vue-components unplugin-auto-import 2. 配置 在vite.config.js文件中配置&#xff0c;配置完重启&#xff08;n…

Leetcode.664 奇怪的打印机

题目链接 Leetcode.664 奇怪的打印机 hard 题目描述 有台奇怪的打印机有以下两个特殊要求&#xff1a; 打印机每次只能打印由 同一个字符 组成的序列。每次可以在从起始到结束的任意位置打印新字符&#xff0c;并且会覆盖掉原来已有的字符。 给你一个字符串 s &#xff0c;你…

数学建模--Seaborn库绘图基础的Python实现

目录 1.绘图数据导入 2. sns.scatterplot绘制散点图 3.sns.barplot绘制条形图 4.sns.lineplot绘制线性图 5.sns.heatmap绘制热力图 6.sns.distplot绘制直方图 7.sns.pairplot绘制散图 8.sns.catplot绘制直方图 9.sns.countplot绘制直方图 10.sns.lmplot绘回归图 1.绘图数…

React中函数式组件与类组件有何不同?

Function Component 与 Class Component 有何不同 目录 Function Component 与 Class Component 有何不同 文章核心观点&#xff1a; 解释一下&#xff1a; 总结&#xff1a; 文章核心观点&#xff1a; Function components capture the rendered values.函数式组件捕获…

【漏洞复现】深信服科技EDR平台存在任意用户登录漏洞

漏洞描述 深信服终端检测响应平台EDR,通过云网端联动协同、威胁情报共享、多层级响应机制,帮助用户快速处置终端安全问题,构建轻量级、智能化、响应快的下一代终端安全系统。 该EDR系统存在任意用户登录漏洞&#xff0c;攻击者通过漏洞可以登录系统后台并获取服务器的敏感信息…

3D印刷电路板在线渲染查看工具

从概念上讲&#xff0c;这是有道理的&#xff0c;因为PCB印制电路板上的走线从一个连接到下一个连接的路线基本上是平面的。 然而&#xff0c;我们生活在一个 3 维世界中&#xff0c;能够以这种方式可视化电路以及相应的组件&#xff0c;对于设计过程很有帮助。本文将介绍KiCad…

在ubuntu20.04上安装arm-linux-gcc 4.4.3

1下载地址 [http://www.friendlyelec.com.cn/download.asp] 2.将 arm-linux-gcc-4.4.3.tar.gz 拷贝到 /bin目录 无法拷贝怎么办&#xff1f; 出现这种情况是 Linux 拷贝文件时权限不够&#xff0c; 运行命令 sudo nautilus&#xff0c; 打开一个具有管理员权限的文件管理器&am…

# DevOps名词定义梳理

DevOps名词定义梳理 极限编程座右铭&#xff1a;如果它令你很受伤&#xff0c;那么就做更多的练习&#xff08;If it hurts, do it more often&#xff09; 经常人们会把这些名词用错&#xff1a; 构建&#xff1a;就是把源代码制成成品的过程&#xff0c;这个过程一般会有单元…

微电网的概念

微电网分布式控制理论与方法  顾伟等 微电网的概念和作用 微电网是由多种分布式电源、储能、负载以及相关监控保护装置构成的能够实现自我控制和管理的自治型电力系统&#xff0c;既可以与电网并网进行&#xff0c;也可以以孤岛运行。 分布式发电是指将容量在兆瓦以内的可再…

mysql接收list参数以及日期格式化

mysql接收list参数 List<MarketAnalysisCompanys> getCompanyReduceData(String companyId,List<String> labelNameList, String beginTime, String endTime);<select id"getCompanyReduceData" resultType"com.spang.wechat.entity.MarketAnaly…