什么是单例模式,有哪些应用?
目录
一、定义
二、应用场景
三、6种实现方式
1、懒汉式,线程不安全。
2、懒汉式,线程安全
3、双检锁/双重校验锁(DCL,即 double-checked locking)
4、静态内部类方式-------只适用于静态域
5、饿汉式
6、枚举
四、总结
一、定义
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
单例模式涉及到一个单一的类,单例类只能自己创建唯一的一个实例,并提供了一个全局访问点使所有其他对象获取到类的唯一实例。
特点:
- 唯一实例:确保类只有一个实例。
- 全局访问点:提供一个全局访问点来获取类的实例。
- 线程安全:在多线程环境中,确保实例的唯一性。
二、应用场景
1、配置管理:应用程序可能需要一个只初始化一次的配置管理器。
2、日志记录:日志记录器通常只需要一个实例,以避免日志信息的混乱。
3、性能优化:某些对象的创建成本很高,使用单例模式可以避免重复创建。
三、6种实现方式
分类:
- 饿汉式:类加载就会导致该单实例对象被创建。
- 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。
1、懒汉式,线程不安全。
在这种情况下,我们只有调用 getInstance 方法, instance 对象才会被创建。
在多线程情况下,很多线程都来请求获取该对象,这样就可能创建出多个对象,导致线程不安全。
/*** 懒汉式 线程不安全*/
public class SingletonLazy {//定义一个私有构造方法private SingletonLazy(){}//创建该类对象private static SingletonLazy instance;//对外提供静态方法获取该对象public static SingletonLazy getInstance(){if(instance==null){instance = new SingletonLazy();}return instance;}
}
2、懒汉式,线程安全
由于上述会出现线程不安全问题,所以我们通过加同步锁,保证每次只有一个线程可以对当前对象进行操作,确保了线程安全。但加锁会影响效率。
/*** 懒汉式 线程安全*/
public class SingletonLazy {//定义一个私有构造方法private SingletonLazy(){}//创建该类对象private static SingletonLazy instance;//对外提供静态方法获取该对象 , 加锁public static synchronized SingletonLazy getInstance(){if(instance==null){instance = new SingletonLazy();}return instance;}
}
3、双检锁/双重校验锁(DCL,即 double-checked locking)
我们使用 volatile 关键字, volatile 关键字可以保证可见性和有序性,这个关键字禁止了对当前修饰的变量上下文重排序。保证了方法的可靠性。采用双锁机制,安全且在多线程情况下能保持高性能。
进行二次判断的原因:
假设有两个线程a,b,他们都去请求我们单例模式下类的实例,当第一个判断的时候,两个线程都会进入判断代码块中进行锁的抢占,最终a抢占到了锁,那么b只能在加锁的代码块外部进行等候。这个时候a创建了对象的实例,完成功能后归还了锁,这个时候线程b马上抢占到了锁,然后进入内部代码块。假如没有第二次判断的话,线程a就会再次创建一个新的对象,导致线程不安全。所以,要在这里再加一次判断。
/*** 懒汉式 双重校验锁*/
public class SingletonLazy {//定义一个私有构造方法private SingletonLazy(){}//创建该类对象private volatile static SingletonLazy instance;//对外提供静态方法获取该对象 , 加双重锁public static SingletonLazy getInstance(){if(instance==null){synchronized (instance.getClass()){if(instance == null){instance = new SingletonLazy();}}}return instance;}
}
4、静态内部类方式-------只适用于静态域
静态内部类单例模式中实例由内部类创建,由于 JVM 在加载外部类的过程中, 是不会加载静态内部类的,只有内部类的属性/方法被调用时才会被加载,并初始化其静态属性。静态属性由于被 static 修饰,保证只被实例化一次,并且严格保证实例化顺序。
/*** 静态内部类方式*/
public class SingletonLazy {//私有构造方法private SingletonLazy() {}//定义静态类private static class SingletonHolder {//静态方法private static final SingletonLazy INSTANCE = new SingletonLazy();}//对外提供静态方法获取该对象public static SingletonLazy getInstance() {return SingletonHolder.INSTANCE;}
}
5、饿汉式
它基于 classloader 机制避免了多线程的同步问题,instance 在类装载时就实例化。
/*** 饿汉式*/
public class SingletonEhan {//私有构造方法private SingletonEhan(){}//创建并实例化该类对象private static SingletonEhan instance = new SingletonEhan();//对外提供静态方法获取该对象public static SingletonEhan getInstance(){return instance;}
}
6、枚举
这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
public enum Singleton { INSTANCE; public void whateverMethod() { }
}
四、总结
一般情况下,使用第5种饿汉式。
相关文章:
![](https://i-blog.csdnimg.cn/direct/b9d56bebd1244027884b38920e744206.png)
什么是单例模式,有哪些应用?
目录 一、定义 二、应用场景 三、6种实现方式 1、懒汉式,线程不安全。 2、懒汉式,线程安全 3、双检锁/双重校验锁(DCL,即 double-checked locking) 4、静态内部类方式-------只适用于静态域 5、饿汉式 6、枚举…...
![](https://www.ngui.cc/images/no-images.jpg)
adb命令操作手机各种开关
打开iqoo手机热点设置 adb shell am start -n com.android.settings/com.android.settings.Settings$\VivoTetherSettingsActivity蓝牙模块 检查蓝牙状态的ADB命令 检查蓝牙开关状态 adb shell settings get global bluetooth_on开启和关闭蓝牙 使用Intent操作蓝牙…...
![](https://www.ngui.cc/images/no-images.jpg)
【分布式存储系统HDFS】架构和使用
分布式存储系统HDFS:架构和使用 目录 引言HDFS简介HDFS的架构 NameNodeDataNodeSecondary NameNode HDFS的工作原理 数据读写流程数据冗余与恢复 HDFS的安装和配置 环境准备HDFS安装步骤HDFS配置文件启动HDFS HDFS的使用 基本命令HDFS Shell操作Java API操作 HDFS…...
![](https://i-blog.csdnimg.cn/direct/6723450206bd47d3b74a18f9dc4478e2.png)
Linux 实验一Linux系统安装
一、实验日期与地址 1、实验日期:2024年 2 月28 日 2、实验地址:S1-504 二、实验目的 1、掌握VMware Workstation建立虚拟机 2、掌握虚拟机环境下安装Centos 7 三、实验环境 VMware Workstation、Centos 7 四、实验内容 1、安装VMware Workstat…...
![](https://i-blog.csdnimg.cn/direct/28ea7e53e71543b5a4ac0a2b54170f4f.png)
【人工智能】深度剖析AI伦理:强化隐私防线,推动算法公平性的核心议题
文章目录 🍊1 人工智能兴起背后的伦理及道德风险1.1 算法偏见与歧视1.2 数据隐私侵权1.3 透明度受限1.4 决策失衡1.5 AI生成内容的危险性 🍊2 建构AIGC伦理观:实现人机共创的永续提升2.1 技术手段与伦理预防2.2 即时警告与紧急关停措施2.3 法…...
![](https://i-blog.csdnimg.cn/direct/7fc200eb614f48c0954e4b7ddf1c6297.png)
如何解决微服务下引起的 分布式事务问题
一、什么是分布式事务? 虽然叫分布式事务,但不是一定是分布式部署的服务之间才会产生分布式事务。不是在同一个服务或同一个数据库架构下,产生的事务,也就是分布式事务。 跨数据源的分布式事务 跨服务的分布式事务 二、解决方…...
![](https://i-blog.csdnimg.cn/direct/923d0d19623a4492b446bc76c1c575ed.png)
牛客周赛50轮+cf955+abc363
D-小红的因式分解_牛客周赛 Round 50 (nowcoder.com) 思路: 巨蠢的题目,ax^2bxca1*a2*x^2(b1*a2b2*a1)xb1*b2,即: aa1*a2,ba1*b2a2*b1,cb1*b2 数据范围很小,直接暴力枚举吧(注意条件) 代码…...
![](https://i-blog.csdnimg.cn/direct/afee6f31b29c4c0388753809222777f6.png)
【MySQL】:对库和表的基本操作方法
数据库使用的介绍 什么是SQL 学习数据库的使用——>基于 SQL编程语言 来对数据库进行操作 重点表述的是“需求”,期望得到什么结果。(至于结果是如何得到的,并不关键,都是数据库服务器在背后做好了) 重点表述的是…...
![](https://www.ngui.cc/images/no-images.jpg)
Library not found for -lstdc++.6.0.9
解决方案一 由于项目已经很多年了,前段时间更新了Xcode发现编译报错lstdc这个库很早以前就被舍弃了,但是一个项目的维护都随着解决bug堆砌出来的,这也导致了我们的项目走上了这条路。 比如 Library not found for -lstdc.6.0.9 报的错&#x…...
![](https://i-blog.csdnimg.cn/direct/236ac30bfb1c45af9af6071d887d0eaf.png)
防火墙之双机热备篇
为什么要在防火墙上配置双机热备技术呢? 相信大家都知道,为了提高可靠性,避免单点故障 肯定有聪明的小伙伴会想到那为什么不直接多配置两台防火墙,然后再将他们进行线路冗余,不就完成备份了吗? 答案是不…...
![](https://www.ngui.cc/images/no-images.jpg)
终端里面ifconfig命令无法运行
在 Ubuntu 以及基于 Debian 的系统中,ifconfig 命令可能不会默认安装,因为自 Ubuntu 17.10 版本开始,系统默认使用 ip 命令作为网络配置的主要工具,而 ifconfig 命令则来自 net-tools 包,该包不再作为标准工具被包含在…...
![](https://www.ngui.cc/images/no-images.jpg)
掌握Python中的文件序列化:Json和Pickle模块解析
Python 文件操作与管理:Open函数、Json与Pickle、Os模块 在Python中,文件是一个重要的数据处理对象。无论是读取数据、保存数据还是进行数据处理,文件操作都是Python编程中不可或缺的一部分。本文将详细介绍Python中文件操作的几种常用方法&…...
![](https://img-blog.csdnimg.cn/img_convert/85fe41f9fa606e243e944bb9a0c84678.png)
WordPress 6.6 “Dorsey多尔西”发布
WordPress 6.6 “Dorsey多尔西”已经发布,它以传奇的美国大乐队领袖 Tommy Dorsey 名字命名。Dorsey 以其音调流畅的长号和作品而闻名,他的音乐以其情感深度和充满活力的能量吸引了观众。 当您探索 WordPress 6.6 的新功能和增强功能时,让您的…...
![](https://i-blog.csdnimg.cn/direct/7e9112b974f846c196bf2798503465a0.png)
核函数支持向量机(Kernel SVM)
核函数支持向量机(Kernel SVM)是一种非常强大的分类器,能够在非线性数据集上实现良好的分类效果。以下是关于核函数支持向量机的详细数学模型理论知识推导、实施步骤与参数解读,以及两个多维数据实例(一个未优化模型&a…...
![](https://i-blog.csdnimg.cn/direct/1e66bc46790d450caf2ef15945fe2d39.png)
二分查找(折半查找)
这次不排序了,对排好序的数组做个查找吧 介绍 二分查找排序英文名为BinarySort,是一种效率较高的查找方法要求线性表必须采用顺序存储结构 基本思路 通过不断地将搜索范围缩小一半来找到目标元素: 1、假定数组为arr,需要查找的…...
![](https://www.ngui.cc/images/no-images.jpg)
arcgis紧凑型切片缓存(解决大范围切片,文件数量大的问题)
ArcGIS 切片缓存的紧凑型存储格式是一种优化的存储方式,用于提高切片缓存的存储效率和访问速度。紧凑型存储格式将多个切片文件合并为一个单一的 .bundle 文件,从而减少文件系统的开销和切片的加载时间。这类格式已经应用很久了,我记得2013我…...
![](https://i-blog.csdnimg.cn/direct/fee2c37ba9ca400ab3a9e92c7f280433.jpeg)
ESP32CAM人工智能教学15
ESP32CAM人工智能教学15 Flask服务器TCP连接 小智利用Flask在计算机中创建一个虚拟的网页服务器服务器,让ESP32Cam通过WiFi连接,把摄像头拍摄到的图片发送到电脑中,并在电脑中保存成图片文件。 Flask是用Python编写的网页服务程序WebServer。…...
![](https://www.ngui.cc/images/no-images.jpg)
Pandas 33个冷知识 0721
Pandas 33个冷知识 从Excel读取数据: 使用 pd.read_excel(file.xlsx) 来读取Excel文件。 写入Excel: 使用 df.to_excel(file.xlsx, indexFalse) 将DataFrame写入Excel文件。 创建日期索引: 使用 df.set_index(pd.to_datetime(df[date])) 创建日期索引。 向后填充缺失值: 使用…...
![](https://i-blog.csdnimg.cn/direct/e2abb17be0684dffbdb6614e67089cbc.png)
C++ map和set的使用
目录 0.前言 1.关联式容器 2.键值对 3.树形结构的关联式容器 3.1树形结构的特点 3.2树形结构在关联式容器中的应用 4.set 4.1概念与性质 4.2使用 5.multiset 5.1概念与性质 5.2使用 6.map 6.1概念与性质 6.2使用 7.multimap 7.1概念与性质 7.2使用 8.小结 &a…...
![](https://www.ngui.cc/images/no-images.jpg)
yarn的安装和配置以及更新总结,npm的对照使用差异
1. Yarn简介 Yarn 是一个由 Facebook 开发的现代 JavaScript 包管理器,旨在提供更快、更安全、更可靠的包管理体验。 1.1 什么是Yarn Yarn 是一个快速、可靠和安全的 JavaScript 包管理器,它通过并行化操作和智能缓存机制,显著提升了依赖安…...
![](https://i-blog.csdnimg.cn/direct/06cd68989ae6405c971942dcb7322bd3.png)
【Git命令】git rebase之合并提交记录
使用场景 在本地提交了两个commit,但是发现根本没有没必要分为两次,需要想办法把两次提交合并成一个提交;这个时候可以使用如下命令启动交互式变基会话: git rebase -i HEAD~N这里 N 是你想要重新调整的最近的提交数。 如下在本地…...
![](https://img-blog.csdnimg.cn/img_convert/ac63375db7c704b9d7d9edc1899a3529.jpeg)
为什么品牌需要做 IP 形象?
品牌做IP形象的原因有多方面,这些原因共同构成了IP形象在品牌建设中的重要性和价值,主要原因有以下几个方面: 增强品牌识别度与记忆点: IP形象作为品牌的视觉符号,具有独特性和辨识性,能够在消费者心中留…...
![](https://i-blog.csdnimg.cn/direct/539bba1091d94c67b16c89c6263e233b.png)
Kubernetes 1.24 版弃用 Dockershim 后如何迁移到 containerd 和 CRI-O
在本系列的上一篇文章中,我们讨论了什么是 CRI 和 OCI,Docker、containerd、CRI-O 之间的区别以及它们的架构等。最近,我们得知 Docker 即将从 kubernetes 中弃用!(查看 kubernetes 官方的这篇文章)那么让我…...
![](https://www.ngui.cc/images/no-images.jpg)
70. 爬楼梯【 力扣(LeetCode) 】
一、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 二、测试用例 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶…...
![](https://i-blog.csdnimg.cn/direct/6210232a77c24a1198e8691919e45c81.png)
R语言优雅的把数据基线表(表一)导出到word
基线表(Baseline Table)是医学研究中常用的一种数据表格,用于在研究开始时呈现参与者的初始特征和状态。这些特征通常包括人口统计学数据、健康状况和疾病史、临床指标、实验室检测、生活方式、社会经济等。 本人在既往文章《scitb包1.6版本发…...
![](https://i-blog.csdnimg.cn/direct/aac8050387a1429b9fe678efe138f357.png)
XMl基本操作
引言 使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中. 之前,我们学习了,用注解的方式来实现MyBatis 接下来我们…...
![](https://i-blog.csdnimg.cn/direct/c718477eb6db4ef38416ecfbefa8edf9.png#pic_center)
Linux——Shell脚本和Nginx反向代理服务器
1. Linux中的shell脚本【了解】 1.1 什么是shell Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁 Shell 既是一种命令语言,有是一种程序设计语言 Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问…...
![](https://i-blog.csdnimg.cn/direct/f99a0f97a88e4e10ba1675cb3b6a140e.png)
pyspark使用 graphframes创建和查询图的方法
1、安装graphframes的步骤 1.1 查看 spark 和 scala版本 在终端输入: spark-shell --version 查看spark 和scala版本 1.2 在maven库中下载对应版本的graphframes https://mvnrepository.com/artifact/graphframes/graphframes 我这里需要的是spark 2.4 scala 2.…...
![](https://i-blog.csdnimg.cn/direct/a62c16c80c89466da441970d0ede69cf.png)
【web】-flask-简单的计算题(不简单)
打开页面是这样的 初步思路,打开F12,查看头,都发现了这个表达式的base64加密字符串。编写脚本提交答案,发现不对; 无奈点开source发现源代码,是flask,初始化表达式,获取提交的表达式࿰…...
![](https://www.ngui.cc/images/no-images.jpg)
Apache Sqoop
Apache Sqoop是一个开源工具,用于在Apache Hadoop和关系型数据库(如MySQL、Oracle、PostgreSQL等)之间进行数据的批量传输。其主要功能包括: 1. 数据导入:从关系型数据库(如MySQL、Oracle等)中将…...
![](/images/no-images.jpg)
拖拽网站怎么做的/泉州seo托管
Oracle Server包括Oracle Instance(进程部分)和Oracle Database(文件部分)。一般情况下,Oracle Instance与Oracle database一一对应。在一台机器上可以安装多个Oracle server,每个Oracle server必须有独立的…...
![](https://www.oschina.net/img/hot3.png)
切实加强政府网站建设与管理/搜索百度指数
2019独角兽企业重金招聘Python工程师标准>>> 格式:IF(Condition,A,B) condition条件成立则执行A,否则执行B。 例如:IF(ret1,from_unixtime(rpttime),) 转载于:https://my.oschina.net/guoying1024/blog/698900...
![](https://img-blog.csdnimg.cn/20200414103944287.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pyaXBlblll,size_16,color_FFFFFF,t_70)
手机刷机网站大全/灰色关键词排名代发
面向对象的程序设计 什么是对象? 对象是内存中专门用来存储数据的一块区域对象中可以存放各种数据(比如:数字,布尔值,代码,字符串),什么都能存。对象由三部分组成:1&am…...
![](http://www.runoob.com/images/up.gif)
wordpress 交易模板/百度最新人工智能
2019独角兽企业重金招聘Python工程师标准>>> Linux crontab命令 Linux 命令大全 Linux crontab是用来定期执行程序的命令。 当安装完成操作系统之后,默认便会启动此任务调度命令。 crond命令每分锺会定期检查是否有要执行的工作,如果有要执行…...
![](https://img-blog.csdnimg.cn/img_convert/ccefcb4e6bfdd804b45c1bac39fbc7be.png)
织梦做导航网站/seo是网络优化吗
本文整理一下使用php和mysql向前端推送数据的过程。数据库部分:1.首先安装服务器,我选择xampp,安装可以选择任意地址。安装完成,打开xampp-control.exe 。选择开启Apache和MySQL:2.浏览器进去http://localhost/phpmyad…...
![](https://img-blog.csdnimg.cn/img_convert/55fd2b2273b5a8b4531f72773c469d6e.gif)
wordpress 小米模板/网站seo快速排名
Stream总览什么是流Stream不是集合元素,它不是数据结构并不保存数据,他是有关算法和计算的,它更像一个高级版本的Iterator。原始版本的Iterator,用户只[md]### Stream总览什么是流Stream不是集合元素,它不是数据结构并不保存数据&…...