【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
单例模式
作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。
| 实现方式 | 优缺点 |
|---|---|
| 饿汉式 | 线程安全,调用效率高 ,但是不能延迟加载 |
| 懒汉式 | 线程安全,调用效率不高,能延迟加载 |
| 双重检测锁 | 在懒汉式的基础上解决并发问题 |
| 静态内部类 | 线程安全,资源利用率高,可以延时加载 |
| 枚举单例 | 线程安全,调用效率高,但是不能延迟加载 |
饿汉式
在类加载的时候立即实例化对象,实现的步骤是先私有化构造方法,对外提供唯一的静态入口方法
public class SingletonInstance1 {private byte[] b1 = new byte[1024*1024];private byte[] b2 = new byte[1024*1024];private byte[] b3 = new byte[1024*1024];// 声明此类型的变量,并实例化,当该类被加载的时候就完成了实例化并保存在了内存中private final static SingletonInstance1 instance = new SingletonInstance1();// 私有化所有的构造方法,防止直接通过new关键字实例化private SingletonInstance1(){}// 对外提供一个获取实例的静态方法public static SingletonInstance1 getInstance(){return instance;}
}
在类加载时直接创建对象可能会造成空间的浪费
–
懒汉式
public class SingletonInstance2 {// 声明此类型的变量,但没有实例化private static SingletonInstance2 instance = null;// 私有化所有的构造方法,防止直接通过new关键字实例化private SingletonInstance2(){}// 对外提供一个获取实例的静态方法public static SingletonInstance2 getInstance(){if(instance == null){// 当instance不为空的时候才实例化instance = new SingletonInstance2();}return instance;}
}
外部调用getInstance()方法时才会创建对象(判断对象是否存在),但是不能保证多线程并发的情况下的线程安全,所以就出现了双重检测锁模式
–
双重检测锁模式
public class SingletonInstance3 {// 声明此类型的变量,但没有实例化,防止指令重排private volatile static SingletonInstance3 instance;// 私有化所有的构造方法,防止直接通过new关键字实例化private SingletonInstance3(){}// 对外提供一个获取实例的静态方法public static SingletonInstance3 getInstance(){if(instance == null){synchronized (SingletonInstance3.class){if(instance == null){// 当instance不为空的时候才实例化instance = new SingletonInstance3();/*1.分配内存空间2.执行构造法法,初始化对象3.把这个对象指向这个空间如果不加volatile 会执行重排序 1 3 2*/}}}return instance;}
}
静态内部类
public class SingletonInstance4 {// 静态内部类public static class SingletonClassInstance{// 声明外部类型的静态常量public static final SingletonInstance4 instance = new SingletonInstance4();}// 私有化构造方法private SingletonInstance4(){}// 对外提供的唯一获取实例的方法public static SingletonInstance4 getInstance(){return SingletonClassInstance.instance;}
}
枚举
public enum EnumSingle {INSTANCE;public EnumSingle getInstance(){return INSTANCE;}
}
–
如何保证线程安全
推荐使用 静态内部类 或者 双重检测锁 配合volatile使用
–
反射破坏单例模式
代码如下
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class LazyMan {private static boolean jiamibiaozhi = false; // 加密标志位// 私有化所有的构造方法,防止直接通过new关键字实例化private LazyMan(){synchronized (LazyMan.class){if(!jiamibiaozhi){ // 防止反射破坏单例jiamibiaozhi = true;}else {throw new RuntimeException("不能试图使用反射破坏异常");}}System.out.println(Thread.currentThread().getName() +"LazyMan");}// 声明此类型的变量,但没有实例化, volatile防止指令重排private volatile static LazyMan instance;// 对外提供一个获取实例的静态方法public static LazyMan getInstance(){if(instance == null){synchronized (LazyMan.class){if(instance == null){// 当instance不为空的时候才实例化instance = new LazyMan();/*1.分配内存空间2.执行构造法法,初始化对象3.把这个对象指向这个空间如果不加volatile 会执行重排序 1 3 2*/}}}return instance;}// 反射破环单列public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// LazyMan lazyMan = LazyMan.getInstance();Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null); // 获取空参构造器declaredConstructor.setAccessible(true); // 暴力反射,设置权限,无视私有构造器LazyMan lazyMan1 = declaredConstructor.newInstance(); // 通过空参构造器创建对象LazyMan lazyMan2 = declaredConstructor.newInstance();System.out.println(lazyMan1);System.out.println(lazyMan2);}
}
反射不能破坏枚举,见源码

相关文章:
【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
单例模式 作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全,调用效率高 ,但是不能延迟加载懒汉式线程安全,调用效率不高,能延迟加载双重检…...
T-SQL语言的数据库交互
T-SQL语言的数据库交互 引言 随着信息技术的不断发展,数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL(Transact-SQL)作为微软SQL Server的重要扩展语言…...
【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)
inode 和 block 的映射 该博文中有详细解释:【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题: 问题一: 我们访问文件,都是用的文件名,没用过 inode 号啊? 之前总是说可以通过一个…...
慧集通(DataLinkX)iPaaS集成平台-业务建模之域
通过左侧导航菜单〖业务建模〗→〖域〗,进入该界面;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面,点击【新建】按钮进入新建页面;输入编码,名称、模块以及对应数据类…...
【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题
【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络,通过对抗生成网络生成少数类样本,平衡欺诈数据中正类样本极…...
android wifi framework与wpa_supplicant的交互
android frmework直接与wpa_supplicant进行交互,使用aidl或者hidl 二、事件 framework注册事件的地方: packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...
初学stm32 --- flash模仿eeprom
目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...
使用C语言实现栈的插入、删除和排序操作
栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...
C语言程序环境和预处理详解
本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...
基于机器学习随机森林算法的个人职业预测研究
1.背景调研 随着信息技术的飞速发展,特别是大数据和云计算技术的广泛应用,各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式,为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步,如深度学习、强化学习等…...
三种文本相似计算方法:规则、向量与大模型裁判
文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度: 比如,RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数,返回前TopK个候选文本。 在评估大模型生成的文本阶段,也需要评估…...
Python语言的计算机基础
Python语言的计算机基础 绪论 在当今信息技术飞速发展的时代,编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能,逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础,探讨计算机科学的基本概念,并帮助…...
Dify应用-工作流
目录 DIFY 工作流参考 DIFY 工作流 2025-1-15 老规矩感谢参考文章的作者,避免走弯路。 2025-1-15 方便容易上手 在dify的一个桌面上,添加多个节点来完成一个任务。 每个工作流必须有一个开始和结束节点。 节点之间用线连接即可。 每个节点可以有输入和输出 输出类型有,字符串,…...
02.02、返回倒数第 k 个节点
02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法,通过两个指针(fast 和 slow),让 fast 指针比 slow 指针…...
Linux手写FrameBuffer任意引脚驱动spi屏幕
一、硬件设备 开发板:香橙派 5Plus,cpu:RK3588,带有 40pin 外接引脚。 屏幕:SPI 协议 0.96 寸 OLED。 二、需求 主要是想给板子增加一个可视化的监视器,并且主页面可调。 平时跑个模型或者服务,…...
怎么修复损坏的U盘?而且不用格式化的方式!
当你插入U盘时,若电脑弹出“需要格式化才能使用”提示,且无法打开或读取其中的数据,说明U盘极有可能已经损坏。除此之外,若电脑在连接U盘后显示以下信息,也可能意味着U盘出现问题,需要修复损坏的U盘&#x…...
语音技术在播客领域的应用(2)
播客是以语音为主,各种基于AI 的语音技术在播客领域十分重要。 语音转文本 Whisper Whisper 是OpenAI 推出的开源语音辨识工具,可以把音档转成文字,支援超过50 种语言。这款工具是基于68 万小时的训练资料,其中包含11.7 万小时的…...
【Linux】应用层自定义协议与序列化
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 应用层 🦋 再谈 "协议"🦋 网络版计算器🦋 序列化 和 反序列化 二:🔥 重新理解 read、…...
深度学习中的张量 - 使用PyTorch进行广播和元素级操作
深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思? 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素…...
gitignore忽略已经提交过的
已经在.gitignore文件中添加了过滤规则来忽略bin和obj等文件夹,但这些文件夹仍然出现在提交中,可能是因为这些文件夹在添加.gitignore规则之前已经被提交到Git仓库中了。要解决这个问题,您需要从Git的索引中移除这些文件夹,并确保…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
