️【设计模式】之单例模式详解:创建者模式中的一颗“明珠”

全文目录:

    • 开篇语
    • 🎯 什么是单例模式?
    • 🗂️ 单例模式的关键特性
    • 🔑 单例模式的实现方式
      • 1. 🌱 懒汉式单例(Lazy Initialization)
      • 2. 🔒 懒汉式单例(线程安全版)
      • 3. ⚙️ 双重检查锁(Double-Checked Locking)
      • 4. 🌐 饿汉式单例(Eager Initialization)
      • 5. 💥 静态内部类(Initialization on Demand Holder Idiom)
    • 📌 单例模式的应用场景
    • 🤔 单例模式的优缺点
      • 优点
      • 缺点
    • 🎓 进阶技巧:如何优化单例模式的实现?
    • 🧩 小结:单例模式的核心与实战技巧
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言
在软件设计中,单例模式被誉为设计模式中的“最小化实例管理专家”。它的核心思想在于确保一个类在整个系统中只有一个实例,并且能提供一个全局访问点。今天,让我们深入探讨单例模式,了解它在创建者模式中的独特魅力、使用场景和常见实现方式。💡


🎯 什么是单例模式?

单例模式(Singleton Pattern)是一种创建型设计模式,其主要目的是保证某个类在系统中只有一个实例,并且提供一个访问该实例的全局访问点。通常用于那些需要共享全局状态的对象,如配置管理器、日志记录器、数据库连接池等。


🗂️ 单例模式的关键特性

  1. 唯一性:单例模式确保某个类在整个系统中只有一个实例。
  2. 全局访问:通过静态方法,可以在任何地方访问这个唯一的实例。
  3. 延迟初始化:单例模式通常采用“懒汉式”实现,在需要时再初始化,节省系统资源。

🔑 单例模式的实现方式

单例模式的实现方式有多种,常见的有以下几种:

1. 🌱 懒汉式单例(Lazy Initialization)

懒汉式是最简单的实现方式,在第一次调用时才创建实例。

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

特点

  • 优点:延迟加载,资源利用率高。
  • 缺点:在多线程环境下不安全,可能会创建多个实例。

2. 🔒 懒汉式单例(线程安全版)

通过同步方法实现线程安全的单例,但会降低效率。

public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}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;}
}

特点

  • 优点:高效,线程安全。
  • 缺点:代码稍复杂,但是目前最优的懒汉式单例实现方式。

4. 🌐 饿汉式单例(Eager Initialization)

饿汉式单例在类加载时就创建实例,因此不需要考虑线程安全问题。

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

特点

  • 优点:简单,线程安全。
  • 缺点:不支持延迟加载,类加载时即创建实例,可能浪费资源。

5. 💥 静态内部类(Initialization on Demand Holder Idiom)

静态内部类实现方式是单例模式中一个较为推荐的实现方式,利用了类加载机制来确保线程安全。

public class Singleton {private Singleton() {}private static class Holder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
}

特点

  • 优点:线程安全,延迟加载,效率高。
  • 缺点:代码结构复杂,理解门槛略高。

📌 单例模式的应用场景

单例模式在以下场景中非常常用:

  1. 配置管理:在系统中需要一个唯一的配置管理器实例,确保不同模块使用相同的配置信息。
  2. 日志管理:在整个应用程序中仅需一个日志记录对象,用于写入日志文件。
  3. 数据库连接池:多个数据库操作共用同一个数据库连接池实例,节省资源。
  4. 缓存:系统缓存的单一实例,便于管理和统一访问。
  5. 系统资源管理:某些系统资源(如文件系统或打印机)需要全局访问。

🤔 单例模式的优缺点

优点

  • 减少内存开销:因为系统中只会有一个实例,不会占用过多的内存。
  • 全局访问:提供一个全局访问点,使得不同模块能够方便地访问同一个实例。
  • 线程安全:结合适当的实现方式,可以在多线程环境下安全地访问单例对象。

缺点

  • 不易扩展:由于类的构造方法是私有的,继承和扩展会比较困难。
  • 测试难度增加:单例模式由于是全局共享的,容易产生“共享状态”,对单元测试不太友好。

🎓 进阶技巧:如何优化单例模式的实现?

  1. 使用反射与序列化保护
    单例模式的一个潜在风险在于可以通过反射和序列化来创建多个实例。可以在构造方法中加入判断逻辑,阻止二次实例化。

    private Singleton() {if (instance != null) {throw new IllegalStateException("Already initialized");}
    }
    
  2. 防止序列化破坏单例
    单例类实现Serializable接口后,可以通过实现readResolve方法来确保序列化后的实例唯一性。

    protected Object readResolve() {return getInstance();
    }
    
  3. 枚举单例
    Java提供了基于枚举的单例实现,这是最简单且有效的单例实现方式,能够自动支持线程安全并防止反射攻击。

    public enum Singleton {INSTANCE;public void doSomething() {// 方法实现}
    }
    

    特点

    • 简单易用,线程安全且防止序列化和反射破坏。

🧩 小结:单例模式的核心与实战技巧

单例模式在创建者模式中堪称经典,通过限制实例数量和全局访问的方式,解决了系统中资源共享的问题。无论是在配置管理、日志记录还是数据库连接池的管理上,单例模式都是开发者的好帮手。

总结小技巧:

  • 在多线程环境下,尽量选择线程安全的实现方式,比如双重检查锁和静态内部类。
  • 如果需要防止反射和序列化破坏单例,可以选择枚举单例实现。
  • 在设计单例时,考虑其使用场景,避免不必要的资源浪费和过度封装。

希望这篇文章帮助你深入理解单例设计模式的实现和应用,为你的开发旅程增添一份智慧!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL--用户权限

1.使用root用户登录MySQL客户端,创建一个名为userl的用户,初始密码为123456;创建一个名为user2的用户,无初始密码。然后,分别使用uesr1、user2登录MySQL 客户端。 创建两个用户 使用user1登录 使用user2登录 2.使用root用户登录&a…

星海智算:skl-videolingo-2.0(AI视频翻译)使用教程

(一)项目介绍 VideoLingo是一款专为视频创作者设计的开源自动化工具,旨在提供从视频字幕生成到声音克隆配音的一站式服务。以下是对VideoLingo的详细介绍: 1、核心功能​ 1.1、一键全自动视频搬运​ 支持从YouTube等平台下载视…

SQL靶场第八关攻略

一.判断类型 输入?id1 and 11-- 输入?id1 and 12--页面都正常,说明不是数值型 输入?id1页面没有回显 加上--页面正常,说明是字符型注入 二.判断列数 输入?id1 order by 3--页面正常 输入?id1 order by 4--页面没有回显,说明一共有三列…

华为HCIP-Datacom H12-821H12-831 (12月最新题库)

备考HCIP-datacom的小伙伴注意啦 !!! 2024年下半年12月份最新(H12-821和H12-831)题库带解析,有需要的小伙伴移动至文章末 H12-821: H12-831: 1.BGP 邻居建立过程的状态存在以下几种:那么建立一个成功的连接所经历的状态机顺序是 A、3-1-2-5-4 B、1-3-5-2-4 C、…

Flask使用长连接

Flask使用flask_socketio实现websocket Python中的单例模式 在HTTP通信中,连接复用(Connection Reuse)是一个重要的概念,它允许客户端和服务器在同一个TCP连接上发送和接收多个HTTP请求/响应,而不是为每个新的请求/响…

MR30分布式 I/O 模块助力 CNC 设备产能飞跃

背景分析 在现代制造业中,CNC 设备扮演着极为关键的角色。然而,CNC 设备在运行过程中也存在着诸多痛点。传统的 CNC 设备往往在控制与通信方面存在局限,其内部的 I/O 系统大多采用集中式架构。这种架构下,一旦需要处理大量的输入输…

远程修改ESXi 6.7管理IP地址

1.启用安全Shell(也就是EXSi可以被SSH访问的功能) 2.使用SecureCRT SSH2连接ESXi主机,现在使用dcui并没有任何反应,在Session标签栏右键点击Disconnect。 The time and date of this login have been sent to the system logs.WA…

Vulnhub靶场 Kioptrix: Level 1 (#1) 练习

目录 0x00 环境准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 方法一:mod_ssl 2.8.42. 方法二:CVE-2003-02013. 方法三:Samba 0x04 总结 0x00 环境准备 下载链接:http://www.kioptrix.com/dlvm/Kioptrix_Level_1.…

消息中间件-Kafka3-kafkaJavaClient小例

消息中间件-Kafka3-kafkaJavaClient小例 Kafak Java Client private static final String KAFKA_TOPIC "kafak-test";private static String bootstrapServers "localhost:9092";private static AdminClient client null;static {Properties config n…

关于光耦合器的常见误解

光耦合器以其提供电气隔离的能力而闻名,广泛应用于从电源到通信系统的各种应用。尽管光耦合器非常普遍,但人们对其特性和用途存在一些常见的误解。本文将揭穿一些最常见的误解,以帮助工程师和爱好者做出更明智的决策。 误解1:光耦…

【简洁明快】使用python读取数据建立pptx (python-pptx图文调整案例)

使用python自动读取数据建立pptx 前言如何使用 Python 自动生成 PPTX第一步:安装所需库第二步:创建一个新的 PPTX第三步:添加幻灯片第四步:添加内容添加文本添加图片第五步:保存 PPTX 图文实操案例(自动读取…

【智体OS】官方上新发布rtphone分布式安卓设备远程控制插件:实现远程访问和管理手机

【智体OS】官方上新发布rtphone分布式安卓设备远程控制插件:实现远程访问和管理手机 dtns.network是一款主要由JavaScript编写的智体世界引擎(内嵌了three.js编辑器的定制版-支持以第一视角浏览3D场馆),可以在浏览器和node.js、d…

Vue智慧商城项目

创建项目 vue组件库 — vant-ui(常用于移动端) Vant 2 - 轻量、可靠的移动端组件库 安装vant npm i vantlatest-v2 -S 引入组件 按需导入和全部导入 全部导入 整个组件库的所有组件都导进来,缺点是增加了代码包体积 main.js import…

提升网站流量的关键:AI在SEO关键词优化中的应用

内容概要 在当今数字时代,提升网站流量已成为每个网站管理员的首要任务。而人工智能的技术进步,为搜索引擎优化(SEO)提供了强有力的支持,尤其是在关键词优化方面。关键词是连接用户需求与网站内容的桥梁,其…

以MP6924A为核心的LLC拓扑学习【一】

PFCLLC: 在PFC(功率因数校正)和LLC(谐振变换器)组成的电源系统中,各个电路有特定的作用,它们协同工作以实现高效率和高功率因数的电能转换。 1. PFC(功率因数校正)电路的作用 PFC电…

实践教程|Transformer Decoder-Only 模型批量生成 Trick

导读 本文给出了一个用单Transformer decoder( GPT)模型进行批量生成时的解决方法。 发现用单 Transformer decoder (Aka GPT)模型进行生成时,因为位置对齐等问题,进行批量生成时十分麻烦。 训练时&#…

DevExpress WPF v24.2新功能预览 - 键盘导航和屏幕阅读器功能增强

DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

threejs相机辅助对象cameraHelper

为指定相机创建一个辅助对象,显示这个相机的视锥。 想要在场景里面显示相机的视锥,需要创建两个相机。 举个例子,场景中有个相机A,想要显示相机A的视锥,那么需要一个相机B,把B放在A的后面,两个…

财务规划的变革:如何推动数据科学的转型和分析

在快速发展的金融世界中,财务专业人士越来越需要超越传统预算方式的数据分析方法,将现代化的预算技术、工具和方法引入到我们的企业发展过程中,并在企业内部发挥更具战略性的作用。数据科学、财务预测和预算分析是企业财务领域成功所必需的核…

PyTorch环境迁移指南

在进行深度学习研究和开发时,我们经常需要在不同计算机之间迁移PyTorch环境。无论是更换新设备还是在多台机器间协同工作,都需要确保环境配置的一致性。本文将详细介绍PyTorch环境迁移的完整流程和注意事项。 环境迁移看似简单,实则暗藏玄机。直接复制文件可能会遇到系统差异带…