设计模式 —— 单例模式

文章目录

    • 一、单例模式
      • 1.1 单例模式定义
      • 1.2 单例模式的优点
      • 1.3 单例模式的缺点
      • 1.4 单例模式的使用场景
    • 二、普通案例
      • 2.1 饿汉式单例模式(Eager Initialization Singleton)
      • 2.2 懒汉式单例模式(Lazy Initialization Singleton)
    • 参考资料

本文源代码地址为 java-demos/singeleton-pattern at main · idealzouhu/java-demos (github.com)

一、单例模式

1.1 单例模式定义

单例模式(Singleton Pattern)是一个比较简单的模式,其定义如下:

Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)

在这里插入图片描述

1.2 单例模式的优点

  • 全局访问:单例对象可以在应用程序的任何地方被访问,而不需要传递对象的引用。这样可以方便地共享对象的状态和功能,简化了对象之间的通信和协作。
  • 节省资源:由于只有一个对象实例存在,可以减少重复创建对象的开销。在需要频繁创建和销毁对象的情况下,单例对象可以显著节省系统资源,提高性能。

1.3 单例模式的缺点

  • 单例模式没有接口,扩展困难
  • 单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

1.4 单例模式的使用场景

在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式,具体的场景如下:

  • 要求生成唯一序列号的环境;
  • 在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以 不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
  • 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
  • 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当 然,也可以直接声明为static的方式)。

二、普通案例

实现单例模式的注意事项主要有:

  • 构造函数私有化:限制产生多个对象。
  • 提供静态的访问方法: 用于外部访问唯一的实例
  • 线程安全性:在懒汉式单例模式中,如果多个线程同时访问 getInstance() 方法并且尝试创建实例,可能会导致创建多个实例。

2.1 饿汉式单例模式(Eager Initialization Singleton)

在饿汉式单例模式中,单例对象在类加载时就已经被初始化,因此不需要担心线程安全问题。

public class EagerSingleton {// 静态成员变量,保存单例对象(final 使对象具备不可变性,从而保证线程安全)private static EagerSingleton instance = new EagerSingleton();// 私有构造方法,防止外部实例化private EagerSingleton() {}// 公共静态方法,返回单例对象public static EagerSingleton getInstance() {return instance;}// 示例方法,用于演示单例的行为public void doSomething() {System.out.println("do something");}public static void main(String[] args) {// 获取单例对象并调用方法EagerSingleton eagerSingleton = EagerSingleton.getInstance();eagerSingleton.doSomething();}
}

getInstance 是一个公共静态方法,用于返回单例对象。由于 INSTANCE 已经在类加载时初始化,因此这种方法被称为“饿汉式”实现。

2.2 懒汉式单例模式(Lazy Initialization Singleton)

懒汉式单例模式的特点是在需要的时候才创建实例,将实例的初始化延迟到第一次调用的时候。

public class LazySingleton {// 静态成员变量,保存单例对象private static LazySingleton instance;// 私有构造方法,防止外部实例化private LazySingleton() {}// 公共静态方法,返回单例对象public static LazySingleton getInstance() {// 双重检查加锁,线程安全if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}// 示例方法,用于演示单例的行为public void doSomething() {System.out.println("Doing something...");}public static void main(String[] args) {// 获取单例对象并调用方法LazySingleton singleton = LazySingleton.getInstance();singleton.doSomething();}
}

getInstance() 是一个公共静态方法,用于返回单例对象。该方法利用双重检查锁保证线程安全:

  1. 首先检查 instance 是否为 null,如果是,则进入同步块。大多数情况下,instance 已经被初始化,因此大多数调用都不会进入同步块,从而避免了不必要的同步开销。
  2. 在同步块内再次检查 instance 是否为 null,以确保线程安全地创建单例对象。

参考资料

《设计模式之禅 (第2版)》

Java基础面试题 | 小林coding (xiaolincoding.com)

手摸手实现基础组件模块 (yuque.com)

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

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

相关文章

Leetcode236经典题目二叉树的最近公共祖先

本次为大家带来的题目是leetcode236二叉树的最近公共祖先 本道题的直观思路是自底向上进行寻找,如果存在的话那么向上返回,如何能够自底向上遍历呢?我们可以利用回溯进行处理,那么需要注意的是进行回溯的时候一定要使用后序遍历来…

too many blocks in cooperative launch at cudaLaunchCooperativeKernel

在使用cudaLaunchCooperativeKernel时出现: cudaErrorCooperativeLaunchTooLarge (error 82) due to “too many blocks in cooperative launch” on CUDA API call to cudaLaunchCooperativeKernel. 问题: 在使用cudaLaunchCooperativeKernel时&…

总线操作与定时

目录 一. 总线定时1.1 同步通信(同步定时方式)1.2 异步通信(异步定时方式)1.3 半同步与分离式通信(了解即可) 二. 总线标准(了解即可)2.1 总线标准的概念2.2 系统总线标准2.3 局部总…

新电脑Win11系统想要降级为Win10怎么操作?

前言 现在的电脑大部分都是Windows 11系统,组装机还好一些,如果想要使用Windows 10,只需要在安装系统的时候选择Windows 10镜像即可。 但是对于新笔记本、厂商的成品机、一体机来说,只要是全新的电脑,基本上都是Wind…

Windows中Git对文件名大小写不敏感的问题解决方法

文章目录 前言一、Git 对文件名大小写不敏感方法1.使用git命令进行修改方法2.关闭git 忽略大小写配置 (可以当前项目设置,也可以全局设置 --global) 二、新的问题(重复的目录)原因分析解决方法 前言 Git是一个免费的、…

C#使用MQTT(一):MQTT服务端

MQTT(Message Queuing Telemetry Transport) 即时通讯协议, 开发商 IBM MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状…

【图论】Dijkstra算法求最短路

一、Dijkstra算法简介 Dijkstra算法是由河南荷兰计算机科学家狄克斯特拉(Dijkstra)于1959年提出的,因此又叫狄克斯特拉算法。 二、初识Dijkstra算法 在使用Dijkstra算法求最短路时,需要用到三个辅助数组: v i s x vis_x visx​:布尔数组&…

【图灵完备 Turing Complete】游戏经验攻略分享 Part.3 存储器

这一章,前面不难,后面难。 教你别这么连线连出问题。 看结果说话,延迟两个时刻输出。 先不管要求,输出一个稳定的信号,看看之前给了延迟元件正好延迟一刻,然后作为输入和那个稳定的信号做一个逻辑运算改变…

国内可以免费使用的gpt网站【九月持续更新】

GPT Hub 是我最近使用的一款智能文本生成工具平台,它支持多种AI模型,包括最新的GPT-4模型,并且可以在国内网络环境中直接访问。以下是我在使用过程中发现的一些特点: 多功能支持:不仅支持代码生成,还涵盖了…

macos OneNote 2016 for Mac 官方pkg下载地址 - macos 10.15 Catalion 可用Onenote版本官方下载地址

macos 10.15 Catalion 版本的系统已经无法正常从应用商店下载到可用的Onenote 应用,原因是版本不受支持, 而且onenote官方链接的应用商店地址https://apps.apple.com/us/app/microsoft-onenote/id784801555?mt12在中国地区也无法访问, 所以中国地区用户如果想使用onenote应用…

抢先看:2024云栖大会体验攻略

这是一场「AI」奇妙之旅。 2024云栖大会定档 9月19日! 期待与你在 杭州云栖小镇 共度一场为期3天的科技盛会 三日主论坛 400分论坛 与并行话题 4万平米 智能科技展区 免费领取云栖大会门票 怎么看、怎么玩、怎么逛 超长干货攻略奉上,请查收 ⬇️…

二开PHP泛目录生成源码 可生成新闻页面和关键词页面——码山侠

PS 本资源提供给大家学习及参考研究借鉴美工之用,请勿用于商业和非法用途,无任何技术支持! 下载i5i.net 泛目录可以用来提升网站收录和排名 合理运用目录可以达到快速出词和出权重的效果 程序小 基本的服务器都带的得动 打开i5i.net——…

ROS的Navigation导航系统move_base

Navigation系统和人在使用地图app进行导航的过程类似,接下来让我们看下面的两幅框图: global_planner(全局规划器)从map _server地图服务器获取global_costmap(全局地图数据),然后根 据输入的导航目的地(move_base_simple/goal)生成全局导航路线(intern…

np.c_ 和 np.r_ 的使用

1. np.c_ 的使用 np.c_ 是 NumPy 库中的一个函数,用于沿着第二轴(列)连接两个或多个数组。这个函数通常用于将两个数组的列合并在一起,而不会改变它们原有的行顺序。np.c_ 是一个非常有用的工具,尤其是在处理需要按列…

Draw.io for Mac/Win:免费且强大的流程图绘制工具

在数字化时代,流程图已成为表达复杂过程和逻辑关系的重要工具。Draw.io(现也称为diagrams.net),作为一款免费且功能强大的流程图绘制工具,无论是对于Mac还是Windows用户,都是不可多得的选择。 一、跨平台兼…

基于51单片机的跑马串口调试波形发生器proteus仿真

地址: https://pan.baidu.com/s/1WTjU_hRJ-fLMTT5g1q-NlA 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectro…

python中.之后的圈c、圈v分别代表什么意思?

python中.之后的圈c、圈v分别代表什么意思? Python中,.之后的圈c表示类的实例方法,而圈v表示类的成员变量。 在面向对象编程中,类是一种抽象的数据类型,实例方法是定义在类中的函数,用于操作类的实例变量…

kubeadm方式安装k8s

⼀、安装环境 1. 安装说明 本次以⼆进制⽅式安装⾼可⽤ k8s 1.28.0 版本,但在⽣产环境中,建议使⽤⼩版本⼤于 5 的 Kubernetes 版本,⽐如 1.19.5 以后。 2. 系统环境 3. ⽹络及版本环境 注:宿主机⽹段、Pod ⽹段、Service ⽹段…

Python案例 | 四阶龙格库塔法简介

1.引言 在数值分析中,龙格-库塔法(Runge-Kutta methods)是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。这些技术由数学家卡尔龙格和马丁威尔海姆库塔于1900年左右发明。 龙格-库塔(Runge-Kutta)方法是一种在工程上应用广泛的高…

59.以太网数据回环实验(2)硬件资源梳理及系统框图

硬件资源梳理介绍: 升腾开发板使用的以太网PHY芯片型号为RTL8211F,是低功耗10-BASE/100-BASE/1000-BASE全双工以太网PHY层芯片,支持 10Mbps、100Mbps 和 1000Mbps以太网通信。I/O 引脚电压可变,符合 IEEE802.3-2005 标准&#xff…