设计模式 - 单例模式(懒汉式、饿汉式、静态内部类、枚举)

news/2024/10/31 20:46:38/

目录

一、单例模式的核心概念

二、实现单例模式的方法

2.1 懒汉式(Lazy Initialization)

2.1.1 线程不安全版本

2.1.2 双重检查锁定(线程安全)

2.2 饿汉式(Eager Initialization)

2.3 静态内部类(Static Inner Class)

2.4 枚举(Enum)

三、单例模式的优缺点

优点

缺点

四、总结


设计模式是在软件设计中为解决特定问题而反复出现的解决方案的描述。它们不是完成任务的具体代码,而是模板或蓝图,指导开发者如何有效地解决问题。设计模式通常涉及类的行为和交互方式,它们可以帮助开发者编写可维护、可扩展和可复用的代码。

单例模式是一种常用的软件设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。这种模式在很多场景下都非常有用,特别是在需要对资源进行集中管理和控制的情况下。

一、单例模式的核心概念

单例模式的核心在于两个方面:

  1. 确保类只有一个实例:通过某种机制来防止多次实例化同一个类。
  2. 提供一个全局访问点:使得应用程序中的任何部分都可以访问到这个唯一的实例。

二、实现单例模式的方法

2.1 懒汉式(Lazy Initialization)

懒汉式单例模式会在第一次调用getInstance方法时才创建实例。

2.1.1 线程不安全版本

java">public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}

2.1.2 双重检查锁定(线程安全)

为了使其线程安全,可以采用同步方法或者双重检查锁定(Double Checked Locking):

java">public class LazySingletonThreadSafe {// 使用volatile关键字保证可见性和有序性private volatile static LazySingletonThreadSafe uniqueInstance;  private LazySingletonThreadSafe() {// 防止反射攻击if (uniqueInstance != null) {throw new IllegalStateException("Singleton instance already created!");}}public static LazySingletonThreadSafe getInstance() {if (uniqueInstance == null) { // 第一次检查synchronized(LazySingletonThreadSafe.class) {if (uniqueInstance == null) { // 第二次检查uniqueInstance = new LazySingletonThreadSafe();}}}return uniqueInstance;}
}

2.2 饿汉式(Eager Initialization)

饿汉式单例模式在类加载的时候就创建了实例,因此没有线程安全问题。

java">public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;}
}

2.3 静态内部类(Static Inner Class)

这种方式结合了懒汉式和饿汉式的优点,实现了线程安全并且只有在第一次调用getInstance方法时才会初始化。

java">public class StaticInnerSingleton {private StaticInnerSingleton() {}private static class SingletonHolder {private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();}public static StaticInnerSingleton getInstance() {return SingletonHolder.INSTANCE;}
}

2.4 枚举(Enum)

枚举可以用来实现单例模式,这是《Effective Java》推荐的方式之一,简洁且线程安全。

java">public enum EnumSingleton {INSTANCE;public void someMethod() {// 实现代码}
}

三、单例模式的优缺点

优点

  1. 节省资源:因为单例模式只允许一个实例存在,所以在内存使用上比较经济。
  2. 简化访问:提供全局访问点,方便在任何地方获取实例。
  3. 易于扩展:可以很容易地扩展原有的功能而不影响其他模块。

缺点

  1. 难以测试单例模式破坏了对象的封闭性,使得在单元测试时很难模拟单例的行为。
  2. 违反单一职责原则:单例类通常承担了过多的责任。
  3. 潜在的并发问题:在多线程环境下需要特别注意线程安全问题。

四、总结

单例模式是一种非常实用的设计模式,尤其适用于那些需要频繁访问且创建成本较高的对象。

然而,在使用单例模式时也需要谨慎,因为它可能会引入一些设计上的问题,特别是当单例类变得过于庞大时。

在现代软件架构中,依赖注入(DI)框架(如Spring)的使用越来越广泛,它提供了一种更加灵活的方式来管理对象的生命周期,因此在很多情况下,单例模式可以通过依赖注入来实现,而不是手动实现。

因为:Spring框架本身就提供了依赖注入(Dependency Injection, DI)机制来管理bean的生命周期,并且默认情况下bean是以单例(Singleton)模式存在的。这意味着,对于大多数场景来说,你只需要声明一个类,并通过适当的注解(如@Service@Repository@Controller等)标记它,Spring容器就会为你管理这个bean的实例化和生命周期。对于同一个bean类型,Spring容器只会创建一个实例,并且每次请求该bean时都会返回相同的实例。


http://www.ppmy.cn/news/1543419.html

相关文章

【Windows11】24H2 内存占用高(截至10月31日)

文章目录 一、问题二、解决三、原因 一、问题 系统版本: 内存只有32GB。 以前只有我在运行数据处理程序的时候内存占用才会很高,日常情况下应该只有40%、50%左右的。 但是24H2,日常情况下内存占用80%以上。 而我只开了很少的应用&#…

ORACLE 11G WINDOWS上面搭建DG,路径对应不起作用

问题现象: 今天在WINDOWS上搭建ORACLE DG时,主备库路径不一样, 比如 主库为:d:\oradata\orcl\ 备库为:e:\oradata\orcl\ 于是在备库的参数中,加了以下参数: db_file_name_convertd:\oradata\o…

计算机网络:网络层 —— IP 协议概述

文章目录 IP 协议概述异构网络互连IP 地址IPv4IPv6 IP 协议概述 网际协议(Internet Protocol,IP)是 TCP/IP 体系结构网际层中的核心协议,也是构成互联网的基础。 IP 协议是一种用于在计算机网络中传输数据的协议,是 TCP/IP 协议组中的网络层…

es(1)(仅供自己参考)

elasticsearch(ES)是一款非常强大的开源搜索引擎,可以帮助我们从海量的数据中快速找到需要的内容。 elastic stack(ELK):elasticsearch结合kibana、Logstash、Beats。被广泛的应用在日志数据分析、实时监控…

《Linux系统编程篇》fork/wait/waitpid/exit函数——基础篇

文章目录 引言fork() 函数概述父子进程 fork函数fork() 的常见问题fork() 的优势与限制 引入wait和waitpid(解决僵尸进程)wait函数waitpid函数:exit函数 结论 命为志存。 —— 朱熹 引言 《Linux系统编程篇》——基础篇首页传送门 本节我们…

基于vue框架的的家政预定服务系统4k26i(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:用户,家政员,服务列表,预约订单,家政订单,服务类型,服务评价,系统收益,家政收益,家常菜 开题报告内容 基于Vue框架的家政预定服务系统开题报告 一、研究背景与意义 随着现代生活节奏的加快和家庭结构的变化,家政服务需求日…

3dmax云渲染插件平台哪家好?

嗨,大家好,我是小白~很多朋友常询问哪个渲染农场更经济。 实际上,在追求低价的道路上,并没有绝对的"最便宜"。渲染服务的价格普遍相差不大,而过于低廉的费用往往难以保证质量。我们应该寻找的是高质量、稳定…

nginx配置转发到elk的kibana的服务器

服务器准备 在135服务器上安装nginx服务 编辑kibana服务器的配置文件 将端口改为监听自己 杀掉之前kibana进程 重新启动kibana服务 因为设置了监听自身,所以前台访问kibana页面报错 此时我们修改nginx配置文件,用grep命令反选不含#和空行的行 将其覆盖原…