【GoF23种设计模式】02_单例模式(Singleton Pattern)

文章目录

  • 前言
  • 一、什么是单例模式?
  • 二、为什么要用单例模式?
  • 三、如何实现单例模式?
  • 总结


前言

提示:设计者模式有利于提高开发者的编程效率和代码质量:

GoF(Gang of Four,四人帮)设计模式由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者合著,介绍了23种经典的设计模式。
分为三大类:创建型模式、结构型模式和行为型模式。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是单例模式?

单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点来获取这个实例。这通常用于需要集中控制或管理资源的场景,例如数据库连接、线程池、配置文件读取等。

二、为什么要用单例模式?

使用单例模式的原因包括但不限于以下几点:

  • 资源控制:确保系统中某个资源仅有一个实例,避免资源浪费或冲突。
  • 全局访问:提供一个全局访问点,使得系统中的任何部分都可以方便地访问该实例。
  • 节省内存:因为只有一个实例存在,所以可以节省系统资源,特别是当对象占用大量内存时。
  • 状态共享:对于需要在多个地方共享状态的情况,单例模式可以确保状态的一致性。
  • 初始化成本高:如果对象的创建过程非常复杂或者耗时,那么使用单例模式可以在第一次使用时才进行创建,从而延迟初始化,提高性能。

三、如何实现单例模式?

单例模式的实现有多种方式,下面是一些常见的实现方法:

1、懒汉式(Lazy Initialization)
懒汉式是在第一次调用 getInstance 方法时才创建实例,这样可以实现延迟加载,节省资源。

public class Singleton {private static Singleton instance;private Singleton() {} // 私有构造函数防止外部实例化public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

优点:实现了真正的懒加载,即只有在真正需要的时候才会创建实例。

缺点:每次调用 getInstance 方法都需要进行同步,这可能会带来性能问题。

2、饿汉式(Eager Initialization)
饿汉式是在类加载时就创建实例,因此不需要同步,性能较好。

public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {} // 私有构造函数防止外部实例化public static Singleton getInstance() {return instance;}
}

优点:没有线程安全问题,也不需要同步,性能较高。

缺点:无论是否使用,都会创建实例,无法实现懒加载。

3、双重检查锁定(Double-Checked Locking)
双重检查锁定是一种优化过的懒汉式实现,减少了不必要的同步操作,提高了性能。

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;}
}

优点:既实现了懒加载,又避免了每次调用 getInstance 时都进行同步,性能较高。

缺点:实现稍微复杂一些,而且需要理解Java内存模型和volatile关键字的作用。

4、静态内部类(Static Inner Class)
静态内部类是另一种实现懒加载的方式,利用了类加载机制确保线程安全。(常用)

public class Singleton {private Singleton() {} // 私有构造函数防止外部实例化private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

优点:线程安全,且实现了懒加载,性能良好,代码简洁。

缺点:与其它方式相比,可能不是最直观的理解方式。


总结

选择哪种实现方式取决于具体的应用场景和需求,后期会新增关于单例模式的具体应用场景。

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

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

相关文章

Node.js day-01

01.Node.js 讲解 什么是 Node.js,有什么用,为何能独立执行 JS 代码,演示安装和执行 JS 文件内代码 Node.js 是一个独立的 JavaScript 运行环境,能独立执行 JS 代码,因为这个特点,它可以用来编写服务器后端…

又要考试了

一、实现无名管道练习&#xff1a;父进程写入管道&#xff0c;子进程读取管道数据。 #include<myhead.h> int main(int argc, const char *argv[]) {int fd[2];char buff[1024]"王吕阳&#xff0c;崔庆权别卷了";char s[1024];if(pipe(fd)-1){perror("pi…

LoadBalancer负载均衡和Nginx负载均衡区别理解

LoadBalancer和Nginx都是用来做负载均衡用的&#xff0c;那二者有什么区别呢&#xff1f; Nginx服务器端的负载均衡&#xff1a; 所有请求都先发到nginx&#xff0c;然后再有nginx转发从而实现负载均衡。LoadBalancer是本地的负载均衡&#xff1a; 它是本地先在调用微服务接口…

Technitium DNS Server的基本使用1(创建主区域,A记录,开启递归查询,递归到114.114.114.114)

Technitium DNS Server Technitium DNS Server搭建 搭建请看博主的上篇博客&#xff0c;内外网的方法都有 链接: 内网搭建Technitium DNS Server详细教程 登陆进去是以下界面 这个界面主要是监控&#xff0c;有访问的时候就会有波动 创建主区域&#xff0c;A记录 写上主区…

Git简介和特点

目录 一、Git简介 二、Git特点 1.集中式和分布式 (1)集中式版本控制系统 (2)分布式版本控制系统 2.版本存储方式的差异 (1)直接记录快照&#xff0c;而非差异比较 3.近乎所有操作都是本地执行 一、Git简介 Git是目前世界上最先进的的分布式控制系统&#xff08;没有之一…

CSS学习记录15

CSS下拉菜单 使用CSS创建可悬停的下拉列表。 下拉式式菜单 .dropdown类使用position:relative,当我们希望将下拉内容放置在下拉按钮的正下方(使用position:absolute)时&#xff0c;需要使用该类。 .dropdown-content 类保存实际的下拉内容。默认情况下它是隐藏的&#xff0…

RabbitMQ全局流量控制

RabbitMQ全局流量控制 流控机制流控是对什么进行控制&#xff1f;rabbitmq进程邮箱流控机制是什么&#xff1f; 流控原理流控原理流程 流控状态显示流控对象流控机制对象主要进程各进程状态情形分析 性能提升提升队列性能方式 当消息积压时&#xff0c;消息会进入到队列深处&am…

大数据平台

大数据行业应用持续升温&#xff0c;特别是企业级大数据市场正在进入快速发展时期。越来越多的企业期望实现数据孤岛的打通&#xff0c;整合海量的数据资源&#xff0c;挖掘并沉淀有价值的数据&#xff0c;进而驱动更智能的商业。随着公司数据爆发式增长&#xff0c;原有的数据…

鸿蒙生态的崛起:开发实践、认证路径与激励策略

目录 前言 鸿蒙生态能力和行业解决方案 1、鸿蒙创新能力 2、鸿蒙行业解决方案 中软鸿蒙生态业务布局 1、深度参与鸿蒙生态建设 2、提供一站式鸿蒙生态服务 &#xff08;1&#xff09;服务目录 &#xff08;2&#xff09;改造过程的关键点 &#xff08;3&#xff09;鸿…

指令遵循数据集IFEval介绍:中英双语

IFEval数据集介绍&#xff1a;评估大语言模型指令遵循能力 1. IFEval数据集提出的问题 随着大语言模型&#xff08;如GPT-4、PaLM 2等&#xff09;在自然语言任务中的广泛应用&#xff0c;模型的指令遵循能力&#xff08;Instruction Following&#xff09;成为一个重要评估指…

基于Qt的上位机通讯库

1.前言 做Qt上位机已经有两年的时间了&#xff0c;上位机主要是和下游器件打交道的&#xff0c;通过modbus、tcp、串口等协议来控制这些设备&#xff0c;通过一定的时序控制&#xff0c;完成所需要的工作流程。这其中最重要的就是通讯了&#xff0c;上位机开发过程中的相当一部…

docker安装mysql5.7

1、宿主机创建映射目录 mkdir -p /data/mysql/log mkdir -p /data/mysql/data mkdir -p /data/mysql/conf这里我放在了/data/mysql目录下 2、拉取mysql镜像 docker pull mysql:5.7注意是5.7版本&#xff0c;如果是8版本操作会略有不同&#xff0c;下篇文章介绍安装8版本的操…

SQLServer利用QQ邮箱做SMTP服务器发邮件

环境 Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) SQL Server Management Studio 15.0.18384.0 SQL Server 管理对象 (SMO) 16.100.46367.54 Microsoft .NET Framework 4.0.30319.42000 操作系统 Windows Server2019 ———————————————— 前言&#xf…

好用的网站-直接复制的文字图标不需要引入

分享一个前端不需要引入的&#xff0c;可以直接复制的图标网站 直接复制放在代码中 特殊符号大全&#xff0c;可直接复制黏贴 (shijianchuo.net)

修改uniapp下拉刷新圆圈颜色

直接看图 修改前就是常规的绿色 自定义更符合我们的软件 直接说方法 修改 在App.vue的style样式里添加一行 .uni-page-refresh--refreshing .uni-page-refresh__path{stroke:#FF2442; }我是通过 不执行 uni.stopPullDownRefresh(); 下拉刷新 之后通过F12看出来的 希望可以帮…

Maven插件打包发布远程Docker镜像

dockerfile-maven-plugin插件的介绍 dockerfile-maven-plugin目前这款插件非常成熟&#xff0c;它集成了Maven和Docker&#xff0c;该插件的官方文档地址如下&#xff1a; 地址&#xff1a;https://github.com/spotify/dockerfile-maven 其他说明&#xff1a; dockerfile是用…

12.11数据结构-图

无向完全图&#xff1a;在无向图中&#xff0c;如果任意两个顶点之间都存在边&#xff0c;则称该图为无向完全图。 有向完全图&#xff1a;在有向图中&#xff0c;如果任意两个顶点之间都存在方向相反的两条弧&#xff0c;则称该图为有向完全图。 含有n个顶点的无向完全图有…

Intel(R) Iris(R) Xe Graphics安装Anaconda、Pytorch(CPU版本)

一、Intel(R) Iris(R) Xe Graphics安装Anaconda 下载网址&#xff1a;https://repo.anaconda.com/archive/ 双击Anaconda3-2024.10-1-Windows-x86_64&#xff0c;一直下一步&#xff0c;选择安装的路径位置&#xff0c;一直下一步就安装完成了。打开Anaconda PowerShell Promp…

git使用教程(超详细)-透彻理解git

一.核心基础 核心概念有六个 首先请把与svn有关的一切概念暂时从你的脑海中移除掉&#xff0c;我们要重新认识本文所讲述的所有概念。 1.worktree worktree是一个目录&#xff0c;你在这里对文件进行增加、删除、修改。也就是我们常说的工作区。在git中worktree必须要与一个…

简单的Java小项目

学生选课系统 在控制台输入输出信息&#xff1a; 在eclipse上面的超级简单文件结构&#xff1a; Main.java package experiment_4;import java.util.*; import java.io.*;public class Main {public static List<Course> courseList new ArrayList<>();publi…