第一个设计模式——单例模式

目录

一、特点:

二、实现单例模式步骤

三、饿汉式

四、懒汉式

五、双重检查锁

六、静态内部类

七、枚举

八、可能被反序列化和反射破坏什么意思?

九、如何解决呢?


一、特点:

  1. 唯一性,单例模式确保程序中只有一个实例存在
  2. 节省内存开销,不用多次创建对象

二、实现单例模式步骤

  1. 私有化构造函数,防止外部实例化
  2. 提供公共获取单例对象的静态方法

三、饿汉式

饿汉式是什么?

        指在类加载时就完成了初始化。

  • java实现
public class Singleton {//创建一个静态的单例对象private static final Singleton instance = new Singleton();//私有化构造函数,防止外部实例化private Singleton(){}//提供公共的获取单例对象的静态方法public static Singleton getInstance(){return instance;}}
  • kotlin实现  
object Singleton {//Kotlin的object关键字自动实现了饿汉式单例
}

优点:是线程安全的,因为JVM在进行类加载的时候,会进行加锁,每个类只有一份class对象,然后类加载的时候就会执行静态代码块、静态变量。

缺点:可能被反序列化和反射破坏、浪费资源,当你不需要单例实例,只想调用类中的静态方法时,它都会帮你执行静态代码块和静态变量,因为类加载。例如:


四、懒汉式

懒汉式是什么?

        是指第一次调用时才初始化

        1.不正确的懒汉式单例模式:

        虽然最后打印的结果是一样的对象,这是只有主线程的情况,但是如果在多线程下呢?

java例子:

koltin例子:

        可以看到如果在多线程下,该对象就会被创建多次,所以这种方法是不对的。

        2.正确的懒汉式单例模式:

  • java实现
public class Singleton {//创建一个静态的单例对象private static Singleton instance = null;//私有化构造函数,防止外部实例化private Singleton(){System.out.println("Singleton正在实例化");}//提供公共的获取单例对象的静态方法public synchronized static Singleton getInstance(){if(instance == null){instance = new Singleton();}return instance;}}
  • kotlin 实现
class Singleton {private constructor(){println("Singleton正在被实例")}companion object{private var instance:Singleton? = null@Synchronizedpublic fun  getInstance():Singleton{if(instance == null){instance = Singleton()}return instance!!}}}

优点:在多线程下,能保证该类只实例一次。

缺点:可能被反序列化和反射破坏、为方法加锁,粒度太大,即锁定的范围过宽。这意味着锁保护的区域较大,包括了多个操作或整个方法,这会对系统的性能和并发能力产生一些负面影响,多个线程可能因为需要访问一个被锁定的方法而排队等待,导致线程资源的低效使用。

进行优化,减小锁的范围:


五、双重检查锁

  • java实现
public class Singleton {//创建一个静态的单例对象private volatile static Singleton instance = null;//私有化构造函数,防止外部实例化private Singleton(){System.out.println("Singleton正在实例化");}//提供公共的获取单例对象的静态方法public  static Singleton getInstance(){if(instance == null){synchronized(Singleton.class) {if(instance == null) {instance = new Singleton();}}}return instance;}
}
  • kotlin实现
class Singleton {private constructor(){println("Singleton正在被实例")}companion object{@Volatileprivate  var instance:Singleton? = nullpublic fun  getInstance():Singleton{if(instance == null){synchronized(Singleton::class.java) {if(instance == null) {instance = Singleton()}}}return instance!!}}
}

优点:线程安全、提高了性能、避免了资源浪费。

缺点:可能被反序列化和反射破坏、结构复杂,要记得加volatile关键字。


六、静态内部类

  • java实现
public class Singleton {//私有化构造函数,防止外部实例化private Singleton(){System.out.println("Singleton正在实例化");}// 静态内部类,只有在第一次被访问时才会被加载private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}}
  • kotlin实现
class Singleton {private constructor(){println("Singleton正在被实例")}companion object{object SingletonHolder{val INSTANCE = Singleton()}public fun getInstance():Singleton{return SingletonHolder.INSTANCE}}
}

优点:线程安全、避免了资源浪费、实现简单

 缺点:可能被反序列化和反射破坏、它的线程安全是依靠类加载,但是类加载是耗性能的,类加载的过程:


七、枚举

  • java实现
public enum Singleton {INSTANCE;// 可以在这里添加其他方法和属性
}
  • kotlin实现
enum class Singleton {INSTANCE;// 可以在这里添加其他方法和属性
}

优点:代码写法简洁优雅、线程安全(通过反编译class文件,可以看到INSTANCE是一个静态变量。那么就是通过类加载来保证线程安全的)、可以防止反序列化和反射破坏单例、并且不用手动私有化构造函数。

缺点:不能继承其它类,因为它内部已经继承了Enum类、它的线程安全是依靠类加载,但是类加载是耗性能的。


八、可能被反序列化和反射破坏什么意思?

        1.反序列化破坏:将一个单例对象进行序列化后,再反序列化,而反序列化的对象和程序对象不是同一个对象。除了枚举的单例,其它的方式都会被反序列化破坏。

        例如,以饿汉式为例子:

        2.反射破坏:通过反射调用类的无参构造函数进行创建出来对象和程序的单例对象不是同一个对象。除了枚举的单例,其它的方式都会被反射破坏

        例如,以饿汉式为例子:

        3.看看枚举的例子:

        反射创建对象,直接报错:

        序列化和反序列化不会破坏对象:


九、如何解决呢?

  • 对于序列化破坏:

  • 对于反射破坏:        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/386318.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt自定义带前后缀图标的PushButton

写在前面 Qt提供QPushButton不满足带前后缀图标的需求,因此考虑自定义实现带前后缀图标的PushButton,方便后续快速使用。 效果如下: 同时可设置前后缀图标和文本之间间隙: 代码实现 通过前文介绍的Qt样式表底层实现 可以得…

HiveSQL中last_value和first_value函数的应用

概述 今天做一个数据分析,其中有一列数据有些有数据有些没数据,因此我们需要把每数据的进行补充进来因此我们需要使用last_value 函数和over 结合使用,但是遇到一个比较奇葩的问题不能按照预期进行处理。 新说原因: 由于我们要处…

vue3-环境变量-JavaScript-axio-基础使用-lzstring-字符串压缩-python

文章目录 1.Vue3环境变量1.1.简介1.2.全局变量的引用1.3.package.json文件 2.axio2.1.promise2.2.安装2.3.配置2.3.1.全局 axios 默认值2.3.2.响应信息格式 2.4.Axios的拦截器2.4.1.请求拦截器2.4.2.响应拦截器2.4.3.移除拦截器2.4.4.自定义实例添加拦截器 3.lz-string3.1.java…

java项目数据库 mysql 迁移到 达梦

目录 一、下载安装达梦数据库 1、下载 2、解压 3、安装 二、迁移 三、更改SpringBoot 的 yml文件 1、达梦创建用户 2、修改yml 一、下载安装达梦数据库 1、下载 下载地址 https://eco.dameng.com/download/ 点击下载 开发版 (X86平台) , 然后选择操作系统并点击立…

“科技创新‘圳’在变革”2025深圳电子展

电子产业作为现代社会的核心驱动力之一,正以前所未有的速度发展。在这样的背景下,深圳作为中国的经济特区和创新高地,又一次迎来了备受瞩目的盛会——2025深圳电子展览会。本次展览会定于2025年4月9日至11日,在深圳会展中心&#…

剪画小程序:手机提取人声和伴奏

在音乐的海洋中,我们常常渴望更纯粹地感受歌手的嗓音魅力。 如今,有了 剪画,人声分离不再是难题! 想象一下,当您沉浸在一首动人的歌曲中,却希望更清晰地捕捉到歌手声音中的每一个微妙情感。 无论是经典老…

算能端侧 AI 盒子 Stable Diffusion 一秒一张图:AirBox BM1684X

本篇文章聊聊基于 端侧 AI 计算设备,20~30 瓦功耗运行大模型的算能 AirBox。 写在前面 去年的双十二的时候,在群里看到了一张照片,“手掌大小的 NUC”,但是能够跑大模型。 这个草就种下了。 今年 7 月初的时候,在上…

学习008-02-04-09 Assign a Standard Image(分配标准图像)

Assign a Standard Image(分配标准图像) This lesson explains how to associate an entity class with a standard image from the DevExpress.Images assembly. This image illustrates the entity class in the following sections of the UI: 本课介…

C# 知识点总结

入门 C#程序在.NET上运行,.NET framework包含两个部分: ①:.NET framework类库 ②:公共语言运行库CLR(.NET虚拟机) CLS(公共语言规范) CTS(通用类型系统) .N…

ubuntu20.04安装nginx,mysql8,php7.4详细教程,包成功

目录 1.更新索引 2.安装 Nginx 1.安装 Nginx: 2.启动 Nginx 服务并设置为开机自启: 3.开放防火墙的 80 端口: 4.检查 Nginx 是否正常运行: 3.安装 MySQL 8.0 1.首先,安装 MySQL 的仓库: 安装过程中你会看…

RewardBench:Evaluating Reward Models for Language Modeling

Leaderboard: https://hf.co/spaces/allenai/reward-bench Code: https://github.com/allenai/reward-bench Dataset: https://hf.co/datasets/allenai/reward-bench 在人类偏好的强化学习(RLHF)过程中,奖励…

【Vulnhub系列】Vulnhub_Seattle_003靶场渗透(原创)

【Vulnhub系列靶场】Vulnhub_Seattle_003靶场渗透 原文转载已经过授权 原文链接:Lusen的小窝 - 学无止尽,不进则退 (lusensec.github.io) 一、环境准备 1、从百度网盘下载对应靶机的.ova镜像 2、在VM中选择【打开】该.ova 3、选择存储路径&#xff0…

【AI大模型】-- 应用部署

一、GPU价格参考 有些在京东就能买到:https://item.jd.com/10065826100148.html美国商务部限制 GPU 对华出口的算力不超过 4800 TOPS 和带宽不超过 600 GB/s,导致最强的 H100 和 A100 禁售。英伟达随后推出针对中国市场的 A800 和 H800。 H100 与 A100&…

CATIA V5R21安装包下载及图文安装教程

大家好,今天给大家分享下catia安装教程 注意安装前请退出杀毒软件,防止误报影响安装进程 下载链接:百度网盘 请输入提取码 提取码:ypc6 01 在电脑D盘新建文件夹命名为CATIA,将下载的软件压缩包放置在该文件夹。 鼠标右击【C…

淘宝测试环境治理实践

去年之前,阿里巴巴的淘天集团测试环境是以领域方式运作:不局限测试环境治理本身,从测试模式方法论及用好测试环境思路引领集团测试环境治理。领域运作最难的是“统一思想”。业务进一步细分调整后,测试环境治理策略理应由业务方自…

【MetaGPT系列】【MetaGPT完全实践宝典——多智能体实践】

目录 前言一、智能体1-1、Agent概述1-2、Agent与ChatGPT的区别 二、多智能体框架MetaGPT2-1、安装&配置2-2、使用已有的Agent(ProductManager)2-3、多智能体系统介绍2-4、多智能体案例分析2-4-1、构建智能体团队2-4-2、动作/行为 定义2-4-3、角色/智…

若能重回白宫,特朗普称将把比特币列为美国战略储备资产!

KlipC报道:当地时间7月29日,美国前总统特朗普参加比特币2024大会,并在会上宣布称,如果重返白宫,他将把比特币列为美国战略储备资产。讲话期间,比特币价格一度上涨到6.9万美元大关。 特朗普表示&#xff1a…

Photos框架 - 自定义媒体选择器(UI预览)

引言 在前面的博客中我们已经介绍了使用媒体资源数据的获取,以及自定义的媒体资源选择列表页。在一个功能完整的媒体选择器中,预览自然是必不可少的,本篇博客我们就来实现一个资源的预览功能,并且实现列表和预览的数据联动效果。…

前端基于 axios 实现批量任务调度管理器 demo

一、背景介绍 这是一个基于 axios 实现的批量任务调度管理器的 demo。它使用了axios、promise 等多种技术和原理来实现批量处理多个异步请求,并确保所有请求都能正确处理并报告其状态。 假设有一个场景:有一个任务列表,有单个任务的处理功能…

PyQt ERROR:ModuleNotFoundError: No module named ‘matplotlib‘

Solution:打开cmd输入指令下载malplotlib pip install matplotlib