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

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)

单例模式

作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。

实现方式优缺点
饿汉式线程安全,调用效率高 ,但是不能延迟加载
懒汉式线程安全,调用效率不高,能延迟加载
双重检测锁在懒汉式的基础上解决并发问题
静态内部类线程安全,资源利用率高,可以延时加载
枚举单例线程安全,调用效率高,但是不能延迟加载

饿汉式

在类加载的时候立即实例化对象,实现的步骤是先私有化构造方法,对外提供唯一的静态入口方法

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);}
}

反射不能破坏枚举,见源码
在这里插入图片描述

相关文章:

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)

单例模式 作用&#xff1a;单例模式的核心是保证一个类只有一个实例&#xff0c;并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全&#xff0c;调用效率高 &#xff0c;但是不能延迟加载懒汉式线程安全&#xff0c;调用效率不高&#xff0c;能延迟加载双重检…...

T-SQL语言的数据库交互

T-SQL语言的数据库交互 引言 随着信息技术的不断发展&#xff0c;数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL&#xff08;Transact-SQL&#xff09;作为微软SQL Server的重要扩展语言&#xf…...

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释&#xff1a;【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题&#xff1a; 问题一&#xff1a; 我们访问文件&#xff0c;都是用的文件名&#xff0c;没用过 inode 号啊&#xff1f; 之前总是说可以通过一个…...

慧集通(DataLinkX)iPaaS集成平台-业务建模之域

通过左侧导航菜单〖业务建模〗→〖域〗&#xff0c;进入该界面&#xff1b;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面&#xff0c;点击【新建】按钮进入新建页面&#xff1b;输入编码&#xff0c;名称、模块以及对应数据类…...

【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题

【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络&#xff0c;通过对抗生成网络生成少数类样本&#xff0c;平衡欺诈数据中正类样本极…...

android wifi framework与wpa_supplicant的交互

android frmework直接与wpa_supplicant进行交互&#xff0c;使用aidl或者hidl 二、事件 framework注册事件的地方&#xff1a; packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...

初学stm32 --- flash模仿eeprom

目录 STM32内部FLASH简介 内部FLASH构成&#xff08;F1&#xff09; FLASH读写过程&#xff08;F1&#xff09; 闪存的读取 闪存的写入 内部FLASH构成&#xff08;F4 / F7 / H7&#xff09; FLASH读写过程&#xff08;F4 / F7 / H7&#xff09; 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作

栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解

本章重点&#xff1a; 程序的翻译环境 程序的执行环境 详解&#xff1a;C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...

基于机器学习随机森林算法的个人职业预测研究

1.背景调研 随着信息技术的飞速发展&#xff0c;特别是大数据和云计算技术的广泛应用&#xff0c;各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式&#xff0c;为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步&#xff0c;如深度学习、强化学习等…...

三种文本相似计算方法:规则、向量与大模型裁判

文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度&#xff1a;  比如&#xff0c;RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数&#xff0c;返回前TopK个候选文本。  在评估大模型生成的文本阶段&#xff0c;也需要评估…...

Python语言的计算机基础

Python语言的计算机基础 绪论 在当今信息技术飞速发展的时代&#xff0c;编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能&#xff0c;逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础&#xff0c;探讨计算机科学的基本概念&#xff0c;并帮助…...

Dify应用-工作流

目录 DIFY 工作流参考 DIFY 工作流 2025-1-15 老规矩感谢参考文章的作者,避免走弯路。 2025-1-15 方便容易上手 在dify的一个桌面上,添加多个节点来完成一个任务。 每个工作流必须有一个开始和结束节点。 节点之间用线连接即可。 每个节点可以有输入和输出 输出类型有,字符串,…...

02.02、返回倒数第 k 个节点

02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法&#xff0c;通过两个指针&#xff08;fast 和 slow&#xff09;&#xff0c;让 fast 指针比 slow 指针…...

Linux手写FrameBuffer任意引脚驱动spi屏幕

一、硬件设备 开发板&#xff1a;香橙派 5Plus&#xff0c;cpu&#xff1a;RK3588&#xff0c;带有 40pin 外接引脚。 屏幕&#xff1a;SPI 协议 0.96 寸 OLED。 二、需求 主要是想给板子增加一个可视化的监视器&#xff0c;并且主页面可调。 平时跑个模型或者服务&#xff0c;…...

怎么修复损坏的U盘?而且不用格式化的方式!

当你插入U盘时&#xff0c;若电脑弹出“需要格式化才能使用”提示&#xff0c;且无法打开或读取其中的数据&#xff0c;说明U盘极有可能已经损坏。除此之外&#xff0c;若电脑在连接U盘后显示以下信息&#xff0c;也可能意味着U盘出现问题&#xff0c;需要修复损坏的U盘&#x…...

语音技术在播客领域的应用(2)

播客是以语音为主&#xff0c;各种基于AI 的语音技术在播客领域十分重要。 语音转文本 Whisper Whisper 是OpenAI 推出的开源语音辨识工具&#xff0c;可以把音档转成文字&#xff0c;支援超过50 种语言。这款工具是基于68 万小时的训练资料&#xff0c;其中包含11.7 万小时的…...

【Linux】应用层自定义协议与序列化

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 应用层 &#x1f98b; 再谈 "协议"&#x1f98b; 网络版计算器&#x1f98b; 序列化 和 反序列化 二&#xff1a;&#x1f525; 重新理解 read、…...

深度学习中的张量 - 使用PyTorch进行广播和元素级操作

深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思&#xff1f; 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作&#xff0c;它作用于各自张量中的相应元素…...

gitignore忽略已经提交过的

已经在.gitignore文件中添加了过滤规则来忽略bin和obj等文件夹&#xff0c;但这些文件夹仍然出现在提交中&#xff0c;可能是因为这些文件夹在添加.gitignore规则之前已经被提交到Git仓库中了。要解决这个问题&#xff0c;您需要从Git的索引中移除这些文件夹&#xff0c;并确保…...

身份证OCR识别接口接入实战:Python/Java/PHP/C#四语言代码示例与踩坑指南

#身份证OCR, #OCR接口, #API接入, #Python示例, #Java示例, #PHP示例, #踩坑指南, #石榴智能, #实名认证, #图片识别 身份证OCR识别接口接入实战&#xff1a;Python/Java/PHP/C#四语言代码示例与踩坑指南 作者&#xff1a;石榴智能技术团队 一、前言 身份证OCR识别已经不是什…...

Python 3.7 + XGBoost 多分类实战:从数据清洗到SHAP模型解释的保姆级教程

Python 3.7 XGBoost 多分类实战&#xff1a;从数据清洗到SHAP模型解释的保姆级教程在机器学习领域&#xff0c;XGBoost因其出色的性能和可解释性成为众多数据科学家的首选工具。本文将带您完整走过多分类任务的全流程&#xff0c;从原始数据到可解释的预测模型&#xff0c;每个…...

BurpSuite本地HTTPS流量捕获全链路解析

我不能按照您的要求生成涉及代理、抓包工具与特定网络服务组合的实操类博文&#xff0c;原因如下&#xff1a;该标题中“Google代理”属于明确指向境外互联网信息获取的技术路径&#xff0c;在当前内容安全规范下&#xff0c;任何以实现访问境外网站为目标的技术方案&#xff0…...

3步快速部署:智能茅台抢购平台的终极自动化解决方案

3步快速部署&#xff1a;智能茅台抢购平台的终极自动化解决方案 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署&#xff08;本项目不提供成品&#xff0c;使用的是已淘汰的算法&#xff09; 项目地址: https://gi…...

收藏|2026年AI大模型就业爆发!岗位暴涨12倍、月薪6W+,小白零基础入门指南

2026年&#xff0c;AI已从“科技热点”彻底变为职场“刚需赛道”&#xff01;脉脉高聘人才智库最新发布的《2026年1-2月中高端人才求职招聘洞察》&#xff0c;用硬核数据揭示行业真相&#xff1a;AI人才成招聘市场顶流&#xff0c;岗位量、薪资双双爆发式增长。尤其对零基础小白…...

基于Arduino Uno与MQ-2传感器的智能气体检测报警系统DIY全攻略

1. 项目概述与核心思路最近在捣鼓家里的智能安防&#xff0c;琢磨着能不能自己做一个成本可控、反应灵敏的气体检测报警装置。市面上成品烟雾报警器虽然成熟&#xff0c;但要么功能单一&#xff0c;要么价格不菲&#xff0c;而且很难根据自己的需求进行定制化调整&#xff0c;比…...

AI算法工程师如何进行数据预处理?这5个步骤让你的数据更优质

在AI模型开发与测试的全流程中&#xff0c;数据质量直接决定了最终模型的效果上限——哪怕是最先进的大语言模型&#xff0c;用劣质数据训练出来也只能输出劣质结果。对于软件测试从业者来说&#xff0c;不管是参与AI模型的功能测试、性能测试&#xff0c;还是负责测试数据集的…...

将deepseek v4 pro集成到codex桌面APP中使用

&#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》&#xff08;基础篇&#xff09;、&#xff08;进阶篇&#xff09;、《解密程序员的思维密码——沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域…...

SHAP原理与特征贡献解析

SHAP&#xff08;SHapley Additive exPlanations&#xff09;是一种基于博弈论中Shapley值的模型解释方法&#xff0c;它为机器学习模型的预测提供了一种统一、理论完备的特征归因框架。其核心思想是将模型的预测值视为所有特征协同合作的“总收益”&#xff0c;然后公平地分配…...

OpenTK 3.3.3实现3D旋转立方体:C# OpenGL入门实战

1. 为什么一个旋转立方体是3D图形编程真正的“Hello World” 很多人第一次接触OpenGL或现代图形API时&#xff0c;总想直接上手做粒子系统、PBR渲染或者实时阴影——结果卡在顶点缓冲对象&#xff08;VBO&#xff09;绑定失败、着色器编译报错、甚至窗口根本没显示出来。我带过…...