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

2.单例模式

基本概念

单例模式:保证一个类只有一个实例,并提供一个访问该实例的全局访问点

常见应用场景

  • 读取配置文件的类一般设计为单例模式
  • 网站计数器
  • 应用程序的日志应用,因为共享日志文件一直处于打开状态,只能有一个实例去操作
  • Spring 中初始化 bean 默认为单例
  • Servlet 编程中,每个 servlet 都是单例
  • Spring MVC / Struts1 框架,控制器对象是单例

单例模式优点

(1) 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如:读取配置、产生其他依赖对象时,可以通过在应用启动时直接产生一个单例对象,然后以永久驻留内存的方式解决

(2) 单例模式可以在系统设置全局变量访问点,优化了共享资源的访问

常见单例实现方式

1. 饿汉式(静态常量)

优点:写法简单,在类加载时就完成了实例化;避免了线程同步问题

缺点:没有达到懒加载的效果,如果没有用到这个实例,将造成内存浪费

结论:可用于实际开发

public class Singleton {/*** 1.构造器私有化*/private Singleton() {}/*** 2.类内部创建对象实例*/private final static Singleton INSTANCE = new Singleton();/*** 3.提供公有静态方法,返回实例对象*/public static Singleton getInstance() {return INSTANCE;}
}

2. 饿汉式(静态代码块)

该方式和静态常量的方式类似,只不过将类实例化的过程放在了静态代码块中;即在类装载的时候,就执行静态代码块中的代码,初始化类的实例;优缺点和静态常量的方式一样

结论:可用于实际开发

public class Singleton {/*** 1.构造器私有化*/private Singleton() {}/*** 2.类内部创建对象属性*/private static Singleton INSTANCE;/*** 3.在静态代码块中创建单例对象*/static {INSTANCE = new Singleton();}/*** 4.提供公有静态方法,返回实例对象*/public static Singleton getInstance() {return INSTANCE;}
}

3. 懒汉式(线程不安全)

优点:起到了懒加载的效果,但只能在单线程的场景下使用

缺点:如果在多线程下,一个线程还在 if 判断语句块,而另一个线程通过了 if 代码块,就会产生多个实例

结论:实际开发中,不推荐使用该方式

public class Singleton {/*** 1.构造器私有化*/private Singleton() {}/*** 2.类内部创建对象属性*/private static Singleton INSTANCE;/*** 3.提供公有静态方法,返回实例对象*/public static Singleton getInstance() {return null == INSTANCE ? new Singleton() : INSTANCE;}
}

4. 懒汉式(线程安全,同步方法)

对方式 3 进行改进,对返回单例对象的 getInstance() 方法添加 synchronized,保证线程安全;即多个线程不能同时调用 getInstance() 方法

优点:解决了线程不安全的问题

缺点:效率太低,多个线程想获取类的实例的时候,执行 getInstance() 方法都要同步;而其实该方法只执行一次实例化代码就够了,其他的线程想获取该类的实例,直接 return 就行了;使用方法同步降低了效率

结论:实际开发中,不推荐使用该方式
public class Singleton {
/**
* 1.构造器私有化
*/
private Singleton() {}

/*** 2.类内部创建对象属性*/
private static Singleton INSTANCE;/*** 3.提供公有静态方法,返回实例对象*/
public static synchronized Singleton getInstance() {return null == INSTANCE ? new Singleton() : INSTANCE;
}

}

5. 双重检查

加入了双重检查代码,解决了线程安全的问题,同时也解决了懒加载的问题,效率较高

结论:可用于实际开发

public class Singleton {/*** 1.构造器私有化*/private Singleton() {}/*** 2.类内部创建对象属性*/private static volatile Singleton INSTANCE;/*** 3.提供公有静态方法,返回实例对象*/public static Singleton getInstance() {if(null == INSTANCE) {// 保证创建实例对象的时候, 只能有一个线程synchronized(Singleton.class) {if(null == INSTANCE) {INSTANCE = new Singleton();}}}return INSTANCE;}
}

6. 静态内部类(推荐)

当外部类 Singleton 装载的时候,内部类 SingletonInstance 并不会立即装载,实现了延迟加载

只有在调用 getInstance() 方法的时候,才使用到内部类,这时候内部类才会装载;而类的装载过程是线程安全的,即保证了线程安全

所以静态内部类这种方式既保证了懒加载,又保证了线程安全

结论:强烈推荐

public class Singleton {/*** 1.构造器私有化*/private Singleton() {}/*** 2.通过静态内部类实例化对象*/private static class SingletonInstance {private static final Singleton INSTANCE = new Singleton();}/*** 3.提供公有静态方法,返回实例对象*/public static Singleton getInstance() {return SingletonInstance.INSTANCE;}
}

7. 枚举(推荐)

借助 JDK1.5 添加的枚举实现单例模式,不仅避免了多线程同步的问题,还能防止反序列化重新创建新的对象

结论:强烈推荐

public enum Singleton {/*** 定义单例对象属性*/INSTANCE;/*** 定义单例对象方法*/public void method() {System.out.println("枚举实现单例");}
}

不同实现方式效率对比
在这里插入图片描述

相关文章:

2.单例模式

基本概念 单例模式:保证一个类只有一个实例,并提供一个访问该实例的全局访问点 常见应用场景 读取配置文件的类一般设计为单例模式网站计数器应用程序的日志应用,因为共享日志文件一直处于打开状态,只能有一个实例去操作Spring…...

【保姆级】Java后端查询数据库结果导出xlsx文件+打印xlsx表格

目录前言一、需求一:数据库查询的数据导出成Excel表格1.1 Vue前端实现导出按钮点击事件1.2 后端根据数据库查询结果生成xlsx文件二、需求二:对生成的xlsx文件调用打印机打印2.1 Vue前端实现按钮事件2.2 后端实现打印前言 最近在弄一个需求,需…...

Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)

文章目录1 JDBC(Java Database Connectivity)1.1 什么是 JDBC?1.2 JDBC 核心思想2 JDBC开发步骤【重点】2.0 环境准备2.1 注册数据库驱动2.2 获取数据库的连接2.3 获取数据库操作对象Statement2.4 通过Statement对象执行SQL语句2.5 处理返回结…...

vue3生命周期

一、Vue3中的生命周期 1、setup() : 开始创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 method 2、onBeforeMount() : 组件挂载到节点上之前执行的函数; 3、onMounted() : 组件挂载完成后执行的函数; 4、…...

Python学习笔记10:开箱即用

开箱即用 模块 python系统路径 import sys, pprint pprint.pprint(sys.path) [,D:\\Program Files\\Python\\Lib\\idlelib,D:\\Program Files\\Python\\python310.zip,D:\\Program Files\\Python\\DLLs,D:\\Program Files\\Python\\lib,D:\\Program Files\\Python,D:\\Progr…...

详解JAVA反射

目录 1.概述 2.获取Class对象 3.API 3.1.实例化对象 3.2.方法 3.3.属性 1.概述 反射,JAVA提供的一种在运行时获取类的信息并动态操作类的能力。JAVA反射允许我们在运行时获取类的属性、方法、构造函数等信息,并能够动态地操作它们。 2.获取Class…...

在nestjs中进行typeorm cli迁移(migration)的配置

在nestjs中进行typeorm cli迁移(migration)的配置 在学习nestjs过程中发现typeorm的迁移配置十分麻烦,似乎许多方法都是旧版本的配置,无法直接使用. 花了挺长时间总算解决了这个配置问题. db.config.ts 先创建db.config.ts, 该文件export了两个对象,其…...

前端工程构建问题汇总

1.less less-loader安装失败问题 npm install less-loader --save --legacy-peer-deps 加上–legacy-peer-deps就可以了 在NPM v7中,现在默认安装peerDependencies,这会导致版本冲突,从而中断安装过程。 –legacy-peer-deps标志是在v7中引…...

某马程序员NodeJS速学笔记

文章目录前言一、什么是Node.js?二、fs文件系统模块三、Http模块四、模块化五、开发属于自己的包模块加载机制六、Express1.初识ExpressGET/POSTnodemon2.路由模块化3.中间件中间件分类自定义中间件4. 跨域问题七、Mysql模块安装与配置基本使用Web开发模式Session认证JWT八、m…...

SpringMVC DispatcherServlet源码(6) 完结 静态资源原理

阅读源码,分析静态资源处理器相关组件: 使用SimpleUrlHandlerMapping管理url -> 处理器映射关系spring mvc使用WebMvcConfigurationSupport注入SimpleUrlHandlerMapping组件DelegatingWebMvcConfiguration可以使用WebMvcConfigurer的配置静态资源url…...

2023年全国最新会计专业技术资格精选真题及答案9

百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 四、材料题 1.某企业为增值税一般纳税人,2019年12月初“应付职工薪酬…...

Web3中文|把Web3装进口袋,Solana手机Saga有何魔力?

2月23日,Solana Web3手机Saga发布新的消息,将推出NFT铸造应用程序Minty Fresh。在Minty Fresh,用户仅需轻点并完成拍摄,就可以直接在手机中进行NFT铸造,并在几秒钟内将其转换为链上NFT,NFT还可以发布在 Ins…...

【配电网优化】基于串行和并行ADMM算法的配电网优化研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

数据结构初阶 -- 顺序表

数据结构初阶 链表的讲解 目录 一. 线性表 1.1 定义 1.2 特点 二. 顺序表 2.1 定义 2.2 代码 2.3 功能需求 2.4 静态顺序表的特点以及缺点 2.5 动态的顺序表 2.6 动态顺序表接口的实现 三. 代码 头文件 主文件 一. 线性表 1.1 定义 线性表(linear li…...

uniapp:3分钟搞定在线推送uni.createPushMessage,uni.onPushMessage

安卓端 在线推送功能演示: 1、dcloud后台申请开通uniPush dcloud后台 (1):找到我的应用 (2):点进去后,各平台信息,点击新增 (3):填…...

C/C++开发,无可避免的多线程(篇一).跨平台并行编程姗姗来迟

一、编译环境准备 在正式进入c/c多线程编程系列之前,先来搭建支持多线程编译的编译环境。 1.1 MinGW(win) 进入Downloads - MinGW-w64下载页面,选择MinGW-w64-builds跳转下载, 再次进行跳转: 然后进入下载页…...

如何把照片的底色修改为想要的颜色

如何给照片更换底色?其实有可以一键给照片更换底色的 APP ,但是几乎都要收费。如果想要免费的给照片更换底色的话,分享两种简单便捷的方法给你。掌握了这项技能,以后就不用店花钱处理啦!1、免费!线上快速 给…...

【高效办公】批量生成固定模板的文件夹名称

老师让你按照他的要求生成每位学生的文件夹,你是学委,让你马上完成该任务,但你又不想是手动一个一个码字,因此聪明的你就看到了本篇文章啦!!! 虽说一个人懒惰,并不是好的事情。 但这个似乎合情合理啊~ 然后,就动手想办法,一开始就真的打算码字了。。 思路 在实际开…...

redis的集群方式

1.主从复制 主从复制原理: 从服务器连接主服务器,发送SYNC命令; 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 主服务器BGSAVE执行完后,向所有从服务…...

温控负荷的需求响应潜力评估及其协同优化管理研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

EtherNet/IP转DeviceNet协议网关详解

一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

网站指纹识别

网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

LLMs 系列实操科普(1)

写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...