技术成神之路:设计模式(一)单例模式
在软件设计中,有时我们希望某个类的实例始终是唯一的,即无论在何处访问这个类,都能够得到同一个实例。单例模式(Singleton Pattern)就是为了解决这个问题而产生的。单例模式确保一个类只有一个实例,并提供一个全局访问点。
1.定义
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。其主要思想是将类的构造函数私有化,并通过一个静态方法来控制实例的创建和访问。
2.常见实现方式
单例模式有多种实现方式,下面介绍几种常见的实现方式:
2.1饿汉式(Eager Initialization)
饿汉式是在类加载时就创建实例,这样可以确保线程安全,并且在类首次使用前完成实例化。
示例代码:
public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {// 私有构造函数,防止外部实例化}public static Singleton getInstance() {return INSTANCE;}
}
优点:简单,易于理解,线程安全
缺点:类加载时即创建实例,可能造成资源浪费
如果你一定会使用该类,这种方式无疑是最简单的方法
2.2 懒汉式(Lazy Initialization)
懒汉式是在第一次调用 getInstance() 方法时创建实例。这种方式避免了饿汉式的资源浪费问题。
示例代码:
public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数,防止外部实例化}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
优点:实现简单,延迟实例化,避免资源浪费
缺点:使用了 synchronized,在高并发情况下性能可能较差
每次调用getInstance()
都会进行同步检查,这样会消耗不必要的资源,不推荐使用
2.3双重检查锁(Double-Checked Locking)
双重检查锁在懒汉式的基础上,通过减少使用 synchronized 来提高性能。
示例代码:
public class Singleton {// volatile关键字确保多线程下的可见性和有序性(禁止字节码重排)private static volatile Singleton instance;private Singleton() {// 私有构造函数,避免外部直接实例化}public static Singleton getInstance() {if (instance == null) { // 第一次检查synchronized (Singleton.class) {if (instance == null) { // 第二次检查instance = new Singleton(); // 实例化}}}return instance; // 返回实例}
}
优点:延迟实例化,提高了性能
缺点:实现复杂,容易出错
同步代码块含义:因为可能会有多个线程同时通过了第一次检查,在进入同步块之后,再次检查可以确保只有一个线程创建实例,最大限度地在提升性能的条件下保证了线程安全。
emm… 个人不喜欢这种笨重写法
2.4 静态内部类(Static Inner Class)
这种方式使用了类加载机制来确保线程安全,同时实现了延迟加载。
示例代码:
public class Singleton {private Singleton() {// 私有构造函数,防止外部实例化}// 静态内部类,利用类加载机制保证线程安全且延迟加载private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
优点:延迟实例化,线程安全,实现简单
缺点:无法传递外部参数
这时候就会有同学要问了,何为类加载机制,问的好,所谓类加载机制就算:JVM 在加载类的过程中,静态内部类 SingletonHolder 中的静态变量 INSTANCE 只会被实例化一次,由JVM保证其线程安全性,所以在多线程环境下可以安全地使用。
2.5 枚举(Enum)
这种方法是Effective Java作者Joshua Bloch推荐的单例实现方式之一,它解决了传统单例模式实现中的一些问题,比如序列化、反射攻击等。
示例代码:
public enum Singleton {INSTANCE;public void doSomething() {// 业务方法}
}
优点:简洁,线程安全,防止反序列化破坏单例
缺点:无法灵活控制实例化过程
使用方法:
Singleton.INSTANCE.doSomething();
特点和优势
-
线程安全性:
枚举类型的实例创建是线程安全的,JVM在加载枚举类型时会通过类加载器保证只实例化一次。因此,多线程环境下也能保证单例的唯一性。 -
防止反射攻击:
枚举类型的实例创建是由JVM控制的,因此无法通过反射来创建枚举类的实例。这样可以防止反射攻击,即使是在枚举类中添加了私有构造函数也不例外。 -
防止序列化问题:
Java枚举类型在序列化和反序列化时会自动处理,确保在序列化和反序列化过程中都是单例的。 -
简洁且高效:
枚举实现单例模式非常简洁,只需声明一个枚举类型即可,不需要额外的代码来保证线程安全和单例特性。
3.单例模式的注意事项
- 线程安全:确保在多线程环境下一个类只有一个实例。
- 延迟加载:尽量避免在类加载时就实例化,除非明确知道实例一定会被使用。
- 防止反射攻击:通过在构造函数中添加判断来防止反射创建多个实例。
- 防止反序列化破坏单例:在实现
Serializable
接口时,提供 `readResolve 方法。
4.总结
五种创建单例的方式,大家按需选择,核心思想都是确保一个类只有一个实例,并提供全局访问点,没有最好的,只有最适合的,理解不同实现方式的优缺点,可以帮助我们在实际开发中选择最合适的方案。
相关文章:
技术成神之路:设计模式(一)单例模式
在软件设计中,有时我们希望某个类的实例始终是唯一的,即无论在何处访问这个类,都能够得到同一个实例。单例模式(Singleton Pattern)就是为了解决这个问题而产生的。单例模式确保一个类只有一个实例,并提供一…...

四、(3)补充beautifulsoup、re正则表达式、标签解析
四、(3)补充beautifulsoup、re正则表达式、标签解析 beautifulsoupre正则表达式正则提取标签解析 beautifulsoup 补充关于解析的知识 还需要看爬虫课件 如何定位文本或者标签,是整个爬虫中非常重要的能力 无论find_all(ÿ…...

Vscode快捷键崩溃
Vscode快捷键崩溃 Linux虚拟机下使用vscode写代码【ctrlA,CtrlC,CtrlV】等快捷键都不能使用,还会出现“NO text insert“等抽象的指令,问题就是不知道什么时候装了一个VIM插件,让他滚出电脑》》》...
Spring Boot中的开发工具与插件推荐
Spring Boot中的开发工具与插件推荐 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊聊Spring Boot中的开发工具与插件推荐。Spring Boot作为一种简…...

qt6 获取百度地图(一)
需求分析: 要获取一个地图, 需要ip 需要根据ip查询经纬度 根据经纬度查询地图 另外一条线是根据输入的地址 查询ip 根据查询到的ip查地图‘ 最后,要渲染地图 上面这这些动作,要进行http查询: 为此要有三个QNet…...
overlap的uORF对TE的抑制程度为什么显著高于non-overlap的uORF
在翻译调控中,上游开放阅读框(uORFs)对主开放阅读框(main ORF)的抑制效果有很大差异,尤其是重叠的uORFs(overlap uORFs)通常比非重叠的uORFs(non-overlap uORFsÿ…...

面向高精度导航定位领域的UM980RTK定位模块
UM980 是和芯星通自主研发的新一代 BDS/GPS/GLONASS/Galileo/QZSS 全系统全频高精度 RTK 定位模块,基于和芯星通自主研发的新一代射频基带及高精度算法一体化GNSS SoC 芯片—NebulasIV 设计。可同时跟踪 BDS, GPS, GLONASS, Galileo, QZSS, NavIC, SBAS, L-Band* 等…...

145-四路16位125Msps AD FMC子卡模块
一、概述 该板卡可实现4路16bit 125Msps AD 功能,是xilinx开发板设计的标准板卡。FMC连接器是一种高速多pin的互连器件,广泛应用于板卡对接的设备中,特别是在xilinx公司的所有开发板中都使用。该AD,DA子卡模块就专门针对xilinx开发…...
服务器被劫持
当服务器被劫持时,可以采取一系列措施来修复和加强安全防护,确保服务器的安全性和数据的完整性。以下是一些建议的步骤和策略:12 确认服务器被劫持:首先需要确认服务器是否被劫持。这可以通过检查服务器的日志、网络流量、以及任…...

康姿百德磁性床垫好不好,效果怎么样靠谱吗
康姿百德典雅款床垫,打造舒适睡眠新体验 康姿百德床垫是打造舒适睡眠新体验的首选,其设计能够保护脊椎健康,舒展脊椎,让您享受一夜好眠。康姿百德床垫的面料选择也非常重要,其细腻亲肤的针织面料给您带来柔软舒适的触…...

[吃瓜教程]南瓜书第5章神经网络
1.M-P神经元 M-P神经元,全称为McCulloch-Pitts神经元,是一种数学模型,用于模拟生物神经元的功能。这个模型是由Warren McCulloch和Walter Pitts在1943年提出的。它是人工智能和计算神经科学领域中非常重要的早期模型。 M-P神经元接收n个输入…...

装饰模式解析:基本概念和实例教程
目录 装饰模式装饰模式结构装饰模式应用场景装饰模式优缺点练手题目题目描述输入描述输出描述题解 装饰模式 装饰模式,又称装饰者模式、装饰器模式,是一种结构型设计模式,允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行…...
211.xv6——3(page tables)
在本实验室中,您将探索页表并对其进行修改,以简化将数据从用户空间复制到内核空间的函数。 开始编码之前,请阅读xv6手册的第3章和相关文件: kernel/memlayout.h,它捕获了内存的布局。kernel/vm.c,其中包含…...
yum使用报错:ImportError: /lib64/libxml2.so.2: file too short
系统版本:Rocky 8.10 报错信息: Traceback (most recent call last):File "/usr/lib64/python3.6/site-packages/libdnf/error.py", line 14, in swig_import_helperreturn importlib.import_module(mname)File "/usr/lib64/python3.6/i…...

【Android面试八股文】你是怎么保证Android设备的时间与服务器时间同步的?(使用NTP和TrueTime方案)
文章目录 一、网络时间协议(NTP)二、使用网络时间协议(NTP)2.1 使用系统提供的 NTP 服务器2.2 使用TrueTime2.2.1 引入TrueTime库2.2.2 初始化 TrueTime2.2.3 用法2.2.4 使用 TrueTime 获取时间2.2.4 自动更新时间2.2.5 注意事项二. 使用 HTTP 请求获取服务器时间2.1. 发送…...

解决Python爬虫开发中的数据输出问题:确保正确生成CSV文件
引言 在大数据时代,爬虫技术成为获取和分析网络数据的重要工具。然而,许多开发者在使用Python编写爬虫时,常常遇到数据输出问题,尤其是在生成CSV文件时出错。本文将详细介绍如何解决这些问题,并提供使用代理IP和多线程…...

SCI一区TOP|徒步优化算法(HOA)原理及实现【免费获取Matlab代码】
目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年,SO Oladejo受到徒步旅行启发,提出了徒步优化算法(Hiking Optimization Algorithm, HOA)。 2.算法原理 2.1算法思想 HOA灵感来自于…...
Android的activity广播无法接收,提示process gone or crashing原因有可能是那些?
当Android的Activity无法接收广播,并且收到“process gone or crashing”的提示时,可能的原因有多种。以下是一些常见的原因和排查步骤: Activity生命周期问题: 如果Activity在广播发送之前就已经被销毁(例如…...
如何将等保2.0的要求融入日常安全运维实践中?
等保2.0的基本要求 等保2.0是中国网络安全领域的基本国策和基本制度,它要求网络运营商按照网络安全等级保护制度的要求,履行相关的安全保护义务。等保2.0的实施得到了《中华人民共和国网络安全法》等法律法规的支持,要求相关行业和单位必须按…...

51单片机嵌入式开发:STC89C52环境配置到点亮LED
STC89C52环境配置到点亮LED 1 环境配置1.1 硬件环境1.2 编译环境1.3 烧录环境 2 工程配置2.1 工程框架2.2 工程创建2.3 参数配置 3 点亮一个LED3.1 原理图解读3.2 代码配置3.3 演示 4 总结 1 环境配置 1.1 硬件环境 硬件环境采用“华晴电子”的MINIEL-89C开发板,这…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...