当前位置: 首页 > 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…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...

Vue 实例的数据对象详解

Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...