设计模式之单例模式精讲
UML图:

- 静态私有变量(即常量)保存单例对象,防止使用过程中重新赋值,破坏单例。
- 私有化构造方法,防止外部创建新的对象,破坏单例。
- 静态公共getInstance方法,作为唯一获取单例对象的入口。
public class Demo1 {public static void main(String[] args) {Singleton singleton1 = new Singleton();Singleton singleton2 = new Singleton();System.out.println(singleton1);System.out.println(singleton2);System.out.println(singleton1 == singleton2);}static class Singleton {public Singleton() {}}
}
- 饿汉式--最简单有效,唯一的缺陷在于当对象占用空间较大时,可能浪费内存空间。
public class Demo2 {public static void main(String[] args) {Demo2 instance = Demo2.getInstance();Demo2 instance2 = Demo2.getInstance();System.out.println(instance);System.out.println(instance2);System.out.println(instance == instance2);}private static final Demo2 singleton = new Demo2();private Demo2() {}public static Demo2 getInstance() {return singleton;}
}
- DCL(Double Check Lock)懒汉式
public class Demo3 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Demo3 instance = Demo3.getInstance();Demo3 instance2 = Demo3.getInstance();System.out.println(instance);System.out.println(instance2);System.out.println(instance == instance2);System.out.println("**************************************");Constructor<Demo3> declaredConstructor = Demo3.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);Demo3 demo3 = declaredConstructor.newInstance();System.out.println(demo3);System.out.println(demo3 == instance);}private static volatile Demo3 SINGLETON;private Demo3() {}public static Demo3 getInstance() {if (SINGLETON == null) {synchronized (Demo3.class) {if (SINGLETON == null) {SINGLETON = new Demo3();}}}return SINGLETON;}
}
- 静态内部类
- 懒加载(Lazy Initialization):
- 实例仅在第一次调用
getInstance()方法时创建,这意味着如果在整个程序运行过程中,单例并未被实际使用,则不会创建其实例,避免了不必要的内存消耗。
- 实例仅在第一次调用
- 线程安全(Thread Safety):
- JVM确保了类的静态初始化只会发生一次,并且是线程安全的。静态内部类的实例化过程会被JVM自动处理并确保其原子性,无需程序员显式添加同步锁。
- 懒加载(Lazy Initialization):
public class Demo4 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Demo4 instance = Demo4.getInstance();Demo4 instance2 = Demo4.getInstance();System.out.println(instance);System.out.println(instance2);System.out.println(instance == instance2);System.out.println("**************************");Constructor<Demo4> declaredConstructor = Demo4.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);Demo4 demo4 = declaredConstructor.newInstance();System.out.println(demo4);System.out.println(demo4 == instance);}private Demo4() {}public static class InnerClass {private static final Demo4 DEMO4 = new Demo4();}public static Demo4 getInstance() {return InnerClass.DEMO4;}
}
- 枚举类--最大的优势就是可以防止通过反射创建新对象。初始化时机: 枚举类型的实例是在类加载时由JVM统一初始化的,这个过程是由JVM的类加载机制保障线程安全的。当枚举类型被首次访问时,JVM会确保枚举类的所有实例都被正确地初始化,且这个初始化过程只执行一次,并在全局范围内保持可见。构造函数的私有化: 枚举类型隐式包含了构造函数,并且默认为私有,不允许外部直接实例化。因此,用户无法随意创建新的枚举实例,确保了在整个系统中只能存在预定义的一组实例。JVM的内存模型: 枚举实例一旦被创建,就会存储在JVM方法区的枚举类的常量池中,每个枚举值都是一个不可变的、唯一引用的对象,这就从根本上杜绝了多线程环境下不同线程创建多个实例的可能性。
public enum Demo5 {INSTANCE;public Demo5 getInstance() {return INSTANCE;}public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Demo5 instance = Demo5.INSTANCE.getInstance();Demo5 instance2 = Demo5.INSTANCE.getInstance();System.out.println(instance);System.out.println(instance.hashCode());System.out.println(instance2);System.out.println(instance2.hashCode());System.out.println(instance == instance2);System.out.println("***************************************************");Constructor<?>[] declaredConstructors = Demo5.class.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {Object demo5 = declaredConstructor.newInstance();System.out.println(demo5);System.out.println(demo5.hashCode());System.out.println(demo5 == instance);}}
}
大家如果需要视频讲解,可以关注下我的B站:
二、设计模式之单例模式的多种实现方式
相关文章:
设计模式之单例模式精讲
UML图: 静态私有变量(即常量)保存单例对象,防止使用过程中重新赋值,破坏单例。私有化构造方法,防止外部创建新的对象,破坏单例。静态公共getInstance方法,作为唯一获取单例对象的入口…...
论文复现3:Stable Diffusion v1
abstract: 通过将图像形成过程分解为去噪自动编码器的顺序应用,扩散模型 (DM) 在图像数据及其他方面实现了最先进的合成结果。此外,他们的公式允许一种指导机制来控制图像生成过程,而无需重新训练。然而,由于这些模型通常直接在像素空间中运行,因此强大的 DM 的优化通常会…...
Halcon与VisionMaster对比
作为一个经验丰富的机器视觉算法工程师,我对于机器视觉软件的评价会基于多年的实践经验和对不同软件功能的深入了解。在评价VisionMaster和Halcon软件时,我会从使用场景、工作效率、使用便捷性等方面进行全面分析,并结合软件的优缺点进行讨论…...
多线程的学习1
多线程 线程是操作系统能够进入运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。 进程:是程序的基本执行实体。 并发:在同一个时刻,有多个指令在单个CPU上交替执行。 并行:在同一时刻,…...
警务数据仓库的实现
目录 一、SQL Server 2008 R2(一)SQL Server 的服务功能(二)SQL Server Management Studio(三)Microsoft Visual Studio 二、创建集成服务项目三、配置“旅馆_ETL”数据流任务四、配置“人员_ETL”数据流任…...
Excel·VBA数组分组问题
看到一个帖子《excel吧-数据分组问题》,对一组数据分成4组,使每组的和值相近 目录 代码思路1,分组形式、可分组数代码1代码2代码2举例 2,数组所有分组形式举例 这个问题可以转化为2步:第1步,获取一组数据…...
【笔记】Hbase基础笔记
启动hbase:进入hbase安装目录 输入bin/start-hbase.sh 打开shell命令行模式:进入hbase安装目录 输入bin/hbase shell 退出shell命令行模式:exit 停止hbase:进入hbase安装目录 输入bin/stop-hbase.sh 启动关闭Hadoop和HBase的顺序一…...
创建vue3项目并集成cesium插件运行
创建vue3项目并集成cesium插件 一、vue项目创建 1、前期准备 node.js&npm或yarn 本地开发环境已经安装好。 参考安装 2、安装vue-cli,要求3以上版本 #先查看是否已经安装 vue -V#安装 npm install -g vue/cli4.5.17 示例:Idea工具 页面 Termin…...
Mac 装 虚拟机 vmware、centos7等
vmware: https://www.vmware.com/products/fusion.html centos7 清华镜像: 暂时没有官方的 m1 arm架构镜像 centos7 链接: https://pan.baidu.com/s/1oZw1cLyl6Uo3lAD2_FqfEw?pwdzjt4 提取码: zjt4 复制这段内容后打开百度网盘手机App,操…...
工厂能耗管控物联网解决方案
工厂能耗管控物联网解决方案 工厂能耗管控物联网解决方案是一种创新的、基于先进技术手段的能源管理系统,它深度融合了物联网(IoT)、云计算、大数据分析以及人工智能等前沿科技,以实现对工业生产过程中能源消耗的实时监测、精确计…...
中间件学习
一、ES 场景:某头部互联⽹公司的好房业务,双⼗⼀前⼀天,维护楼盘的运营⼈员突然接到合作开发商的通知,需要上线⼀批热⻔的楼盘列表,上传完成后,C端⼩程序⽀持按楼盘的名称、户型、⾯积等产品属性全模糊搜索…...
iOS开发进阶(十一):ViewController 控制器详解
文章目录 一、前言二、UIViewController三、UINavigationController四、UITabBarController五、UIPageViewController六、拓展阅读 一、前言 iOS 界面开发最重要的首属ViewController和View,ViewController是View的控制器,也就是一般的页面,…...
修改mysql密码
1.在此处文件夹下打开cmd 2.输入命令mysqladmin -uroot -p旧密码 password 新密码 3.在navicat进行测试连接...
uniapp 使用命令行创建vue3 ts 项目
命令行创建 uni-app 项目: vue3 ts 版 npx degit dcloudio/uni-preset-vue#vite-ts 项目名称注意 Vue3/Vite版要求 node 版本^14.18.0 || >16.0.0 如果下载失败,请去gitee下载 https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts…...
一周学会Django5 Python Web开发-Django5模型定义
锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计41条视频,包括:2024版 Django5 Python we…...
kingbaseESV8逻辑备份还原
数据库逻辑备份还原 sys_dump -h127.0.0.1 -Usystem -f/home/kingbase/db01.dmp db01 ksql -h127.0.0.1 test system -c drop database db01 ksql -h127.0.0.1 test system -c create database db01 ksql -h127.0.0.1 -Usystem -ddb01 -f/home/kingbase/db01.dmp --------…...
FreeRtos作业1
1.总结keil5下载代码和编译代码需要注意的事项 代码写完之后的操作流程 2.总结STM32Cubemx的使用方法和需要注意的事项 选择芯片型号 生成代码 3.总结STM32Cubemx配置GPIO的方法 4、使用定时器2让黄灯闪烁 /* USER CODE END Header */ /* Includes --------------------------…...
spring boot dynamic 动态数据数据源配置连接池
前言 我们可以使用 dynamic-datasource 来快速实现多数据源,但是多数据源配置连接池 以及说明文档都是收费的。 这里整理的连接池的配置以及配置说明 连接池配置 (druid或者 hikari 选择一个即可) 特此说明 如果配置配到了 spring.datasour…...
vue3中如何使用 watch 函数来观察响应式数据的变化
前言 在 Vue 3 中,可以使用 watch 函数来观察响应式数据的变化。这个函数可以在组件的 setup 函数中使用。watch()方法还可以实现更多复杂的功能,比如异步获取数据并在数据更新时重新渲染页面。 代码示例 1、以下是一个使用 Vue 3 watch 函数的简单示例…...
自建机房私有云吗?
大家好,我是小码哥,之前一种有没搞清楚公有云、私有云的概念,今天算是弄清楚了,这里给大家分享一下公有云、私有云的区别,以及自建机房算不算私有云! 其实私有云(Private Cloud)和公…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
