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…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...