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

介绍单例模式

描述

保证一个类只有一个实例,并且提供一个全局访问点

场景:

重量级的对象,不需要多个实例,如线程池,数据库连接池

实现

1. 懒汉模式
  • 延迟加载的方式 只有在真正使用的时候,才开始实例化
  • 线程安全问题
  • double check 加锁优化
  • 编译器(JIT) cpu有可能对指令进行重排序,导致使用到尚未初始化的实例,可以通过添加volatile关键字,对于volatile修饰的字段,可以防止指令重排
class LazySingleton{private volatile static LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance(){if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();// 1.分配空间 2.初始化 3.引用赋值}}}return instance;}
}

备注:
javap -v XXX.class可以看class文件的字节码

2. 饿汉模式
  • 类加载的初始化阶段就完成了实例的初始化,本质上是基于JVM类加载机制,保证实例的唯一性
  • 类加载的过程:
    • 加载二进制数据到内存中,生成对应的class数据结构
    • 连接:验证、准备(给类的静态成员变量赋默认值)、解析
    • 初始化:给类的静态变量赋值
      注意:
    • 只有在真正使用对应的类时,才会触发初始化
class HungrySingleton{private static final long serialVersionUID = 4416608876659526091L;private static HungrySingleton instance = new HungrySingleton();private HungrySingleton(){}public static HungrySingleton getInstance(){return instance;}
}
3. 静态内部类
  • 本质上是利用类的加载机制保证线程安全
  • 只有在实际使用的时候,才会触发类的初始化,所以也是懒加载的一种形式
class InnerClassSingleton{private static class InnerClassHolder{private static InnerClassSingleton instance = new InnerClassSingleton();}private InnerClassSingleton(){}public static InnerClassSingleton getInstance(){return InnerClassHolder.instance;}
}
4. 反射攻击实例
public class HungrySingletonTest {public static void main(String[] args) throws Exception {HungrySingleton instance = HungrySingleton.getInstance();HungrySingleton instance1 = HungrySingleton.getInstance();System.out.println(instance);System.out.println(instance1);//        // 反射获取实例Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);HungrySingleton instance2 = declaredConstructor.newInstance();System.out.println(instance2);  } 
}class HungrySingleton{ private static HungrySingleton instance = new HungrySingleton();private HungrySingleton(){if (instance != null) {throw new RuntimeException("单例不允许创建多个实例!");}}public static HungrySingleton getInstance(){return instance;} 
}
5. 枚举

枚举类型支持反序列化的操作 并且不能用反射攻击
其他类型支持反序列化操作案例

public class HungrySingletonTest {public static void main(String[] args) throws Exception {HungrySingleton instance = HungrySingleton.getInstance();HungrySingleton instance1 = HungrySingleton.getInstance();System.out.println(instance);System.out.println(instance1);//        // 反射获取实例
//        Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();
//        declaredConstructor.setAccessible(true);
//        HungrySingleton instance2 = declaredConstructor.newInstance();
//        System.out.println(instance2);// 序列化HungrySingleton instance2 = HungrySingleton.getInstance();
//        ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("testSerializable"));
//        oss.writeObject(instance2);
//        oss.close();ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));HungrySingleton o = (HungrySingleton) ois.readObject();ois.close();System.out.println(o == instance2);}}class HungrySingleton implements Serializable{private static final long serialVersionUID = 4416608876659526091L;private static HungrySingleton instance = new HungrySingleton();private HungrySingleton(){if (instance != null) {throw new RuntimeException("单例不允许创建多个实例!");}}public static HungrySingleton getInstance(){return instance;}public Object readResolve() throws ObjectStreamException {return getInstance();}
}

相关文章:

介绍单例模式

描述 保证一个类只有一个实例&#xff0c;并且提供一个全局访问点 场景&#xff1a; 重量级的对象&#xff0c;不需要多个实例&#xff0c;如线程池&#xff0c;数据库连接池 实现 1. 懒汉模式 延迟加载的方式 只有在真正使用的时候&#xff0c;才开始实例化线程安全问题…...

【C++修行之道】类和对象(五)日期类的实现、const成员、取地址及const和取地址操作符重载

目录 一、 日期类的实现 Date.h 1.1 GetMonthDay函数&#xff08;获取某年某月的天数&#xff09; 问&#xff1a;这个函数为什么不和其他的函数一样放在Date.cpp文件中实现呢&#xff1f; 1.2 CheckDate函数&#xff08;检查日期有效性&#xff09;、Print函数&#xff08;…...

来腾讯第4天,我已经焦虑昏了啊!

大家好&#xff0c;我是白露啊。 今天在看到一个实习生在抱怨&#xff0c;给我笑惨了。 标题是&#xff1a;“腾讯实习第4天&#xff0c;焦虑昏了”&#xff01; 他写道&#xff1a;“怎么办啊牛爷爷们&#xff0c;什么都不会。业务看不懂&#xff0c;文档看不懂&#xff0c;…...

MacOS升级ruby版本

MacOS自带ruby版本是2.x&#xff0c;可以通过“ruby -v”查看版本号 $ ruby -v ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin22]homebrew安装的ruby版本号可以通过“brew info ruby”命令参看 $ brew info ruby > ruby: stable 3.3.2 (bottled)…...

【MySQL数据库基础】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 …...

QT系列教程(9) 主窗口学习

简介 任何界面应用都有一个主窗口&#xff0c;今天我们谈谈主窗口相关知识。一个主窗口包括菜单栏&#xff0c;工具栏&#xff0c;状态栏&#xff0c;以及中心区域等部分。我们先从菜单栏说起 菜单栏 我们创建一个主窗口应用程序, 在ui文件里的菜单栏里有“在这里输入”的一个…...

【C++进阶】深入STL之 栈与队列:数据结构探索之旅

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;模拟实现list与迭代器 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀stack和queue &#x1f4…...

SpringBoot发邮件服务如何配置?怎么使用?

SpringBoot发邮件需要的参数&#xff1f;邮件发送性能如何优化&#xff1f; 在SpringBoot项目中配置发邮件服务是一个常见的需求&#xff0c;它允许我们通过应用程序发送通知、验证邮件或其他类型的邮件。AokSend将详细介绍如何在SpringBoot中配置发邮件服务。 SpringBoot发邮…...

AutoCAD Mechanical机械版专业的计算机辅助设计软件安装包下载安装!

AutoCAD机械版作为一款专业的计算机辅助设计软件&#xff0c;不仅具备卓越的二维绘图功能&#xff0c;更是拥有令人瞩目的3D建模工具&#xff0c;为机械设计师们提供了前所未有的创作空间。 在AutoCAD机械版的3D建模环境中&#xff0c;用户可以借助一系列简洁明了的命令&#…...

json.load报错AttributeError: ‘str‘ object has no attribute ‘load‘

with open(json_file, r) as f:data json.load(f)要写个简单的数据处理脚本&#xff0c;报错AttributeError: ‘str’ object has no attribute ‘load’&#xff0c;查看了一下&#xff0c;路径正确&#xff0c;查了半天博客&#xff0c;不知道错在哪里。 回头一看 jsons_pa…...

单词记忆(第二周)

transplant: trans - plant 移植 perceive: per - ceive 察觉 paraphrase: para - ph - rase 释义 prospect&#xff1a; pro - s - pect 前景 access: ac - cess 进入&#xff0c;通道,访问 generous; gene - rous 慷慨的&#xff0c;丰富的 lecture: lec - ture 讲座 …...

RAG:如何从0到1搭建一个RAG应用

通过本文你可以了解到&#xff1a; 什么是RAG&#xff1f;如何搭建一个RAG应用&#xff1f;目前开源的RAG应用有哪些&#xff1f; 大模型学习参考&#xff1a; 1.大模型学习资料整理&#xff1a;大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业…...

leetcode:67二进制求和

题目链接&#xff1a;67. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:string addBinary(string a, string b) {int stralen a.size(), strblen b.size();int curtc;int Maxlen max(stralen, strblen);vector<int> stra;vector<i…...

大模型日报2024-06-10

大模型日报 2024-06-10 大模型资讯 无需矩阵乘法的语言模型在亿参数规模上表现优异 摘要: 研究表明&#xff0c;无需矩阵乘法的语言模型在亿参数规模上仍能保持顶级性能。这一发现挑战了传统神经网络依赖矩阵乘法的观点&#xff0c;展示了在GPU优化之外的新可能性。 博弈论助力…...

【博士每天一篇文献-综述】Modularity in Deep Learning A Survey

阅读时间&#xff1a;2023-12-8 1 介绍 年份&#xff1a;2023 作者&#xff1a;孙浩哲&#xff0c;布朗克斯医疗卫生系统 会议&#xff1a; Science and Information Conference 引用量&#xff1a;4 论文主要探讨了深度学习中的模块化&#xff08;modularity&#xff09;概念…...

Sentinel不使用控制台基于注解限流,热点参数限流

目录 一、maven依赖 二、控制台 三、基于注解限流 四、热点参数限流 五、使用JMeter验证 一、maven依赖 需要注意&#xff0c;使用的版本需要和你的SpringBoot版本匹配&#xff01;&#xff01; Spring-Cloud直接添加如下依赖即可&#xff0c;baba已经帮你指定好版本了。…...

HTML做成一个端午节炫酷页面

做成端午节页面之前&#xff0c;先了解一下端午节的由来&#xff1a; 1.起源与历史&#xff1a; 端午节起源于中国&#xff0c;始于春秋战国时期&#xff0c;至今已有2000多年历史。 最初是古代百越地区&#xff08;长江中下游及以南一带&#xff09;崇拜龙图腾的部族举行图…...

解决Ubuntu系统/usr/lib/xorg/Xorg占用显卡内存问题原创

在Ubuntu系统中&#xff0c;/usr/lib/xorg/Xorg进程占用显卡内存的问题可能会影响系统性能&#xff0c;特别是在使用GPU进行计算任务时。以下是一些解决方法&#xff0c;可以帮助你减少或解决这个问题&#xff1a; 1. 更新显卡驱动 首先&#xff0c;确保你使用的是最新版本的…...

【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(附源码)(下篇)

作者&#xff1a;后端小肥肠 上篇&#xff1a;【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现&#xff08;上篇&#xff09;_spring security activiti7-CSDN博客 目录 1.前言 2. 核心代码 2.1. 流程定义模型管理 2.1.1. 新增流程定义模型数据 …...

解密Spring Boot:深入理解条件装配与条件注解

文章目录 一、条件装配概述1.1 条件装配的基本原理1.2 条件装配的作用 二、常用注解2.1 ConditionalOnClass2.2 ConditionalOnBean2.3 ConditionalOnProperty2.4 ConditionalOnExpression2.5 ConditionalOnMissingBean 三、条件装配的实现原理四、实际案例 一、条件装配概述 1…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...