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

单例模式(Singleton Pattern)

目录

1.什么是单例模式:

2.单例模式存在的原因:

3.单例模式的优缺点:

4.创建方式:

1. 单线程单例模式立即创建(饿汉式):

          2. 单线程单例模式延迟创建(懒汉式):

5.多线程下测试两种模式存在哪些问题

1.先测试饿汉式,代码如下:

2.测试懒汉式,修改 run 方法创建对象

6.两种模式简单对比:

7.其他的单例模式:


1.什么是单例模式:

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

2.单例模式存在的原因:

一些对象的存在只需要唯一的一个,例如,缓存池和线程池。如果线程池存在多例的话,会导致资
源使用过量,缓存多个的话,会导致数据不一致

3.单例模式的优缺点:

优点:

  • 在内存中只有一个对象,节省内存空间
  • 避免频繁的创建销毁对象,可以提高性能
  • 避免对共享资源的多重占用,简化访问
  • 为整个系统提供一个全局访问点

缺点:

  • 没有接口,不能继承,
  • 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

4.创建方式:

创建一个 maven 项目 singleton

1. 单线程单例模式立即创建(饿汉式):

创建类cn.xs.singleton.Hunchback
public class Hunchback {/* 创建唯一一个单例对象 */private static Hunchback singleton = new Hunchback();/*** 不能让外界直接创建对象,所以设置私有构造器*/private Hunchback() {}/*** 单例对象的全局访问点** @return*/public static Hunchback getInstance() {return singleton;}
}

2. 单线程单例模式延迟创建(懒汉式):

在创建类 cn.xs.singleton.Lazybones
public class Lazybones {/* 创建唯一一个单例对象 */private static Lazybones singleton = null;/*** 不能让外界直接创建对象,所以设置私有构造器*/private Lazybones() {}/*** 单例对象的全局访问点** @return*/public static Lazybones getInstance() {if (singleton == null) {singleton = new Lazybones();}return singleton;}
}

5.多线程下测试两种模式存在哪些问题

新建测试类 cn.xs.singleton.SingletonTest

1.先测试饿汉式,代码如下:

public class SingletonTest extends Thread {@Overridepublic void run() {Hunchback singleton = Hunchback.getInstance();System.out.println(singleton);}/*** 测试方法** @param args*/public static void main(String[] args) {for (int i = 0; i < 10; i++) {SingletonTest singletonTest = new SingletonTest();singletonTest.start();}}
}
输出的都是同一个对象,没有线程安全问题,但是不能延迟加载

2.测试懒汉式,修改 run 方法创建对象

@Override
public void run() {Lazybones singleton = Lazybones.getInstance();System.out.println(singleton);
}
控制台输出了两个对象,可见,懒汉式存在线程安全问题
解决方式一:
在方法上加上 synchronized,保证对临界资源的同步互斥访问
/**
* 单例对象的全局访问点
*
* @return
*/
public synchronized static Lazybones getInstance() {if (singleton == null) {singleton = new Lazybones();}return singleton;
}
这种方式虽然解决了问题,但是当有线程在执行方法时,不管有没有创建对象,其他线程都会在外等候里面的线程执行完毕,有没有一种方式可以解决这个问题,提高代码执行效率
解决方式二:
在方法中创建对象部分设置同步块
public static Lazybones getInstance() {if (singleton == null) {synchronized (Lazybones.class) {if (singleton == null) {singleton = new Lazybones();}}}return singleton;
}
分析:当还没有创建对象的时候,如果被多个线程同时进入方法执行,比如线程 1,线程 2 进来执行方法,两个线程同时判断外层 if 时,都为 true ,都进入外层 if 执行,当走到同步块时,比如线程 1 进入同步块执行代码,线程 2 只能在外面等着,当线程 1 创建完对象执行完同步块后,线程 2 再进入同步块执行代码,在同步块中,线程 2 判断内层 if ,结果为 false ,不用再创建对象,再有别的线程来执行方法,就不会再一直等待前一个线程了,因为外层 if 已经永远为 false

6.两种模式简单对比:

饿汉式:线程安全,调用率高,但是不能延迟加载
懒汉式:线程安全,调用率不高,可以延迟加载

7.其他的单例模式:

双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题,不建议使用)
静态内部类式(线程安全,调用效率高。但是,可以延时加载)
枚举式(线程安全,调用率高,不能延时加载)
对比五种模式,如何选用?
单例对象占用资源少,不需要延迟加载,枚举式比饿汉式好
单例对象占用资源大,需要延迟加载,静态内部类式比懒汉式好

相关文章:

单例模式(Singleton Pattern)

目录 1.什么是单例模式&#xff1a; 2.单例模式存在的原因&#xff1a; 3.单例模式的优缺点&#xff1a; 4.创建方式&#xff1a; 1. 单线程单例模式立即创建&#xff08;饿汉式&#xff09;&#xff1a; 2. 单线程单例模式延迟创建&#xff08;懒汉式&#xff09;&#xf…...

docker file和compose

文章目录1.dockerfile&#xff08;单机脚本&#xff09;1.概念2.原理3.dockerfile核心四步4.命令2.docker compose1.概念2.注意事项3.常用字段4.常用命令1.dockerfile&#xff08;单机脚本&#xff09; 1.概念 通过脚本&#xff0c;生成一个镜像&#xff0c;并运行对应的容器…...

如何解决thinkphp验证码不能显示问题?

thinkPHP做验证码这一块,可以使用自带的验证码扩展,具体步骤如下: 一、安装扩展 composer require topthink/think-captcha 二、模版中使用 将原来静态页面的验证码图片替换为{:captcha_img()},这个会自动生成验证码图片。 <div>{:captcha_img()}</div> 或者 &…...

Vue极简使用

Vue安装Vue模板语法安装Vue 安装nodejs 这里我安装的是14.5.4版本 https://nodejs.org/download/release/v14.15.4/解压后配置一下环境变量就行 安装cnpm镜像 (这个安装的版本可能过高&#xff0c;后面安装Vue可能出问题) npm install -g cnpm --registryhttps://registry…...

【Nacos】Nacos配置中心服务端源码分析

上文说了Nacos配置中心客户端的源码流程&#xff0c;这篇介绍下Nacos配置中心服务端的源码。 服务端的启动 先来看服务启动时干了啥&#xff1f; init()方法上面有PostConstruct&#xff0c;该方法会在ExternalDumpService实例化后执行。 com.alibaba.nacos.config.server.s…...

第十五章 栅格数据重分类、栅格计算器、插值分析

文章目录第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例&#xff1a;分类统计面积第五节 坡度矢量分级图生成第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第三…...

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图 CS5260是一款高度集成的TYPEC转VGA转换方案芯片。 CS5260输出端接口:外接高清VGA设备如:显示器投影机电视带高清的设备&#xff0c;广泛应用于 笔记本Macbook Air 12寸USB3.1输出端对外接高清VGA设备如:显示器投影机电视…...

winform开发心得

最近一直在从事winform的开发&#xff0c;每次都是需要从网上查找资料才能对应具体风格要求&#xff0c;现在总结一下。 ui方面可以使用CSkin对应的一套ui&#xff0c;使用步骤 1.在窗口界面&#xff0c;工具箱空白处点击右键&#xff0c;弹出菜单有个”选择项“&#xff0c;点…...

学习周报-2023-0210

文章目录一 在SUSE11sp3系统中将openssh从6升级到8一 需求二 系统环境三 部署流程1.上传编译安装的软件包2.安装 gcc编译软件3.安装依赖zlib4.安装依赖openssl5.安装openssh二 在CentOS-6.9配置apache服务&#xff08;3&#xff09;---虚拟主机配置一 定义二 系统环境三 基于域…...

百度富文本UE的问题集合

百度富文本编辑能上传视频成功但是在浏览器不能播放、显示的问题百度富文本视频封面空白问题百度富文本编辑器UMEditor 添加视频无法删除百度富文本编辑器结果存数据库取出来到js赋值报错怎么让浏览器重新加载修改过的JS文件&#xff0c;而不是沿用缓存里的百度富文本编辑能上传…...

在Linux上安装node-v14.17.3和npm-6.14.13

记录&#xff1a;374场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;安装node-v14.17.3-linux-x64环境。包括node-v14.17.3和npm-6.14.13。node命令应用和npm命令应用。版本&#xff1a;JDK 1.8 node v14.17.3 npm 6.14.13官网地址&#xff1a;https://nodejs.org/下载地址…...

机器学习框架sklearn之特征降维

目录特征降维概念特征选择过滤式①低方差特征过滤②相关系数③主成分分析特征降维 0维 标量 1维 向量 2维 矩阵 概念 降维是指在某些限定条件下&#xff0c;降低随机变量&#xff08;特征&#xff09;个数&#xff0c;得到一组“不相关”主变量的过程 注&#xff1a;正是…...

java实现二叉树(一文带你详细了解二叉树的)

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《数据结构》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我唯一…...

学弟学妹少走弯路,超完整算法刷题路线出炉

大家好&#xff0c;我是帅地。 本篇文章主要讲解下面三个事&#xff1a; 1、自己学习算法的一些经历 2、大家学习算法存在的一些普遍问题 3、给大家规划的算法刷题路线 一、算法学习往事 记得当初学了 C 语言就开始刷题了&#xff0c;刷题倒不是面试&#xff0c;而是为了…...

Windows截取gif动态图的软件 ScreenToGif 的安装、使用教程

一、概述 &#x1f449;GIF&#xff08;Graphics Interchange Format&#xff09;&#xff0c;又称图形交换格式&#xff0c;是一种公用的图像文件格式标准&#xff0c;于1987年由Compu Serve公司成功研发并推出。 &#x1f449;GIF用于以超文本标志语言方式显示索引彩色图像&a…...

C++程序设计——多态:虚函数、抽象类、虚函数表

注&#xff1a;以下示例均是在VS2019环境下 一、多态的概念 通俗来讲&#xff0c;多态就是多种形态&#xff0c;当不同的对象去完成某个行为时&#xff0c;会产生出不同的状态。即不同继承关系的类对象&#xff0c;去调用同一函数时&#xff0c;产生不同的行为。 比如”叫“这…...

OpenMMLab AI实战营 第6课 语义分割与MMSegmentation

第6课 语义分割与MMSegmentation 1. 语义分割简介 任务&#xff1a;将图像按照物体的类别分割成不同的区域&#xff0c;等价于对每个像素进行分类应用 无人驾驶人像分割智能遥感医疗影像分析 语义分割 vs 实例分割 vs 全景分割 语义分割&#xff1a;仅考虑像素的类别&#xf…...

产业互联网是对互联网的衍生和进化,也是一次重塑和再造

互联网并不仅仅只是充当撮合和中介的角色&#xff0c;它应当具备更多的功能和意义。只有这样&#xff0c;它的发展才能够真正全面和完善。产业互联网的衍生和出现&#xff0c;正是在互联网进化的基础之上出现的。这是我们看到之所以会有那么多的互联网玩家投身到产业互联网的浪…...

Shell脚本之——Hadoop3单机版安装

目录 1.解压 2.文件重命名 3.配置环境变量 4.hadoop-env.sh 5.core-site.xml 6. hdfs-site.xml 7. mapred-site.xml 8.yarn-site.xml 9.完整脚本代码(注意修改主机名) 10.重启环境变量 11.初始化 12.启动服务 13.jps查询节点 1.解压 tar -zxf /opt/install/hadoo…...

代码随想录NO39 |0-1背包问题理论基础 416.分割等和子集

0-1背包问题理论基础 分割等和子集1. 0-1背包问题理论基础(二维数组实现)2. 0-1背包问题理论基础 二&#xff08;一维数组实现&#xff09;1. 0-1背包问题理论基础(二维数组实现) 背包问题一般分为这几种&#xff1a; 0-1背包问题&#xff1a;有n件物品和一个最多能背重量为w…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...