几种场景的单例模式思考总结(饿汉、懒汉、线程安全懒汉、反射破坏、反序列化破坏)

本文主要是介绍几种场景的单例模式思考总结(饿汉、懒汉、线程安全懒汉、反射破坏、反序列化破坏),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天先直接上代码,后续在补充一下单例模式的定义。。

饿汉式单例模式(线程安全):

public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

懒汉式单例模式(非线程安全):

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

懒汉式单例模式(线程安全,双重检查锁定):

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

反射破坏单例(非线程安全):

其中反射破坏单例是指通过反射机制,可以绕过单例模式的控制,从而在单例类的构造方法中多次创建实例,破坏了单例模式的设计意图。

所以通过在单例类的构造方法中增加判断,如果已经存在实例,则抛出异常或返回已存在的实例。

public class Singleton {private static Singleton instance;private Singleton() {if (instance != null) {throw new RuntimeException("Cannot instantiate singleton class using reflection");}}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

反序列化破坏单例(线程安全):

反序列化破坏单例是指在使用序列化和反序列化机制时,可能会破坏单例模式的设计。Java 的序列化机制允许将对象转换为字节序列,以便于存储或传输,而反序列化则是将字节序列还原为对象。
**在单例类中增加 readResolve() 方法是为了在对象反序列化时返回同一实例,从而保证单例的唯一性。**这样可以防止在反序列化时创建多个实例,保持了单例模式的设计意图。
在给定的代码中,readResolve() 方法返回的是单例类的静态实例 instance,这意味着无论在何种情况下反序列化该对象,都将返回同一个实例。这样可以确保反序列化的对象与已存在的单例实例相同,避免了创建新的实例,从而保持了单例的唯一性。
需要注意的是,readResolve() 方法的访问控制符应该是 private,以确保只有单例类本身可以调用该方法,防止在外部通过反射等方式调用。

import java.io.Serializable;public class Singleton implements Serializable {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}// 在反序列化过程中,readResolve() 方法会在对象反序列化时被调用,直接返回单例实例,确保单例的唯一性。protected Object readResolve() {return instance;}
}

这篇关于几种场景的单例模式思考总结(饿汉、懒汉、线程安全懒汉、反射破坏、反序列化破坏)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/867624

相关文章

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Python从零打造高安全密码管理器

《Python从零打造高安全密码管理器》在数字化时代,每人平均需要管理近百个账号密码,本文将带大家深入剖析一个基于Python的高安全性密码管理器实现方案,感兴趣的小伙伴可以参考一下... 目录一、前言:为什么我们需要专属密码管理器二、系统架构设计2.1 安全加密体系2.2 密码强度策略三、核心功能实现详解

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

Flutter打包APK的几种方式小结

《Flutter打包APK的几种方式小结》Flutter打包不同于RN,Flutter可以在AndroidStudio里编写Flutter代码并最终打包为APK,本篇主要阐述涉及到的几种打包方式,通... 目录前言1. android原生打包APK方式2. Flutter通过原生工程打包方式3. Futte

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M