设计模式之单例模式

设计模式C++实现(4)——单例模式 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。单例模式 阅读详情

单例模式是日常开发中经常使用的模式之一,需要大家对它有足够的了解。尽管单例模式理解相对其它模式简单,但是在一些特殊情况下,实现单例模式也需要特别注意。

定义

用来创建独一无二的,只有一个对象实例的类。在实际项目中,单例模式使用非常频繁,例如:线程池、数据库连接池、缓存、日志对象、Spring默认Bean对象等。在这些情况下,若使用过多实例,可能会导致系统资源使用过量、数据不一致等问题。

大家可能会问,创建全局静态变量也能做到如此效果,为什么还会出现一个单例模式呢?没错,全局静态变量确实可以实现如此效果,可是全局变量是在程序启动时就已经创建好对象了,如果该对象占用极大内存并且使用相对较少,就会造成内存资源浪费。使用单例模式,我们可以在需要的时候才去创建对象并且只实例化一次。

实现

单例模式根据实现方式可以分为两种:懒汉式和饿汉式。

懒汉式,顾名思义就是使用的时候才会进行实例化,延迟加载。代码如下:

public class Singleton {
		private static Singleton INSTANCE;
	
		private Singleton(){
			if (INSTANCE != null) {
				throw new RuntimeException(this.getClass() + "不具有该Constructor方法");	
			}
		}
		public static Singleton newInstance() {
                  if(INSTANCE==null){
                       INSTANCE = new Singleton();
                   }
			return INSTANCE;
		}
}

使用private修饰构造方法,为了防止该类被实例化。另外构造函数中判断INSTANCE是否为空,是为了防止使用反射强行执行构造函数实例化,违反单例结果。

饿汉式,顾名思义就是一开始就进行实例化。代码如下:

   public class Singleton {
		private static final Singleton INSTANCE = new Singleton();
		private Singleton() {
			if (INSTANCE != null) {
				throw new RuntimeException(this.getClass() + "不具有该Constructor方法");	
			}
		}
		public static Singleton newInstance() {
			return INSTANCE;
		}
    }

大家是不是觉得单例模式特别简单,其实上述两种实现方式还是有点问题。以懒汉式来说,newInstance()方法,其中我们判断INSTANCE是否为空,不为空则进行实例化,这段代码在单线程中运行确实没有什么问题,但是在多线程环境中,假设现在有两个线程同时判空,那么两个线程都会进行实例化,这个时候,就是有问题的。下面我们就来简单介绍一下,多线程环境中如何实现单例模式。

线程安全的单例

饿汉式是在JVM加载该类的时候就会进行实例化,所以它是线程安全的。上述实现的懒汉式代码,如何解决才能实现线程安全的呢?大家首先想到的应该是加锁,没错,最简单的实现方式是这样的:

synchronized

public static synchronized Singleton newInstance() {
        if(INSTANCE==null){
            INSTANCE = new Singleton();
         }
         return INSTANCE;
}

采用synchronized同步关键字,能够确保多线程执行的时候,只有一个线程能够真正的进行实例化。这种方式简单是简单,可是有不好的地方,当我们第一次调用的时候,确实需要同步,但是在以后调用的时候,多个线程每次只能有一个线程获得实例,这性能肯定是不好的。

双重检查锁

上述我们知道,单纯的加锁会引起性能问题。现在我们思考一下,有没有一种方式,只会在第一次的时候进行加锁,以后都不会涉及同步。双重检查锁就是这样,先判断对象是否为空,再进行加锁进行实例化,这样只会在第一次的时候是同步操作,以后都不会经过锁操作,避免出现性能问题。代码如下:

public static Singleton newInstance() {
        if(INSTANCE==null){
            synchronized(Singleton.class){
                if(INSTANCE==null){
                     INSTANCE = new Singleton();
                }
            }
         }
         return INSTANCE;
}

大家请注意,使用双重检查锁的时候,一定要在申明变量的时候加上volatile关键字,例如:

private volatile static Singleton singleton;

这是为什么呢?在INSTANCE = new Singleton();这一行代码中,分为三个步骤:1.分配内存空间。2.初始化对象。3.将对象指向分配的内存空间。关于这三个步骤,由于2和3两个步骤之间没有太大关联,所以编译器在执行的时候,可能会进行指令重排,导致2和3执行顺序颠倒,引起另外一个线程读取到还未进行初始化的对象。为了解决这个问题,就必须使用volatile,它会防止指令重排。

上述都是采用加锁的方式实现线程安全,有没有不使用加锁的方式呢?肯定有,比如下面我们使用的这两种方式,

内部类实现

public class Singleton {
		private Singleton() {}
		public static Singleton newInstance() {
			return SingletonHolder.instance;
		}
             private static class SingletonHolder{
                 private static Singleton instance=new Singleton();
             }
}

这种方式不仅是线程安全的,并且是延迟加载的,只有在第一次调用newInstance()时,才会创建Singleton实例。这里主要应用了内部类和类的初始化方式,内部类被申明为private,外部类不能对它进行初始化,只能由newInstance()方法进行初始化。这种方式没有涉及到锁操作,所以在高并发的情况下性能优越。

枚举实现

枚举的特性应该不用介绍吧,天生就是单例的,所以使用枚举方式,性能也是非常优越的。

public enum Singleton {
		INSTANCE();
		public void print(){
			System.out.println("我只是一个单实例:"+this);
		}
}

总结

单例模式分为懒汉式和饿汉式。对于频繁使用的对象,特别是一些占内存较大的对象,使用单例模式可以节约资源,并且由于new操作的次数减少,可以减轻GC的压力。在多线程的环境下,要注意单例模式的线程安全。

java设计模式之单例模式——Singleton pattern 设计模式故事会:https://blog.youkuaiyun.com/weixin_40205234/article/details/90664824 单例模式 单例模式(Singleton pattern)是java中最常见的设计模式之一。该模式属于创建型设计模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一... 阅读详情

相关推荐

mac搭建ios自动化环境之WebDriverAgent配置

一、WebDriverAgent 1、简单介绍: WebDriverAgent是facebook为苹果公司开发的一款自动化测试工具,github上有下载资源;另外appium安装后也会自动安装自带的WebDriverAgent;可以用自带的,也可以从github下载并替换自带的; 2、不同appium版本自带WebDriverAgent默认路径不同 1)appium 1.10.1之前版本: npm方式安装: /usr/local/lib/node_modules/appium/node_modules/a

qq_30237715的博客 2765

设计模式-单例模式(Singleton Pattern)

单例模式 定义 确保一个类只有一个实例,并为整个系统提供一个全局访问点 (向整个系统提供这个实例)。 类型 创建型。 适用场景 网站访问量计数器。 项目中用于读取配置文件的类。 Spring中,每个Bean默认都是单例的,这样便于Spring容器进行管理。 优点 由于单例模式只生成了一个实例,所以能够节约系统资源、减少性能开销、提高系统效率。 缺点 不适合用于变化频繁的对象;如果实例化的对象长...

kaven 5158

手把手教你搞定EMC EFT测试:从电源线到信号线的完整整改实战(附常见失败原因)

本文详细解析了EMC EFT测试中的常见问题及整改措施,从电源线到信号线的完整实战方案。通过四步定位法和成本最优整改策略,帮助工程师有效应对电快速脉冲群干扰,提升产品通过率并降低成本。

weixin_30920597的博客 499

23种设计模式中的单例模式(Singleton Pattern)

本篇文章将23种设计模式中的单例设计模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

Basilisk vs. STK:开源航天仿真工具在Windows上的实战体验与生态对比

本文对比了开源航天仿真工具Basilisk与商业软件STK在Windows平台上的实战体验与生态差异。从技术架构、安装配置、使用成本、功能覆盖、社区生态到适用场景,全面分析了二者的优劣势,为航天工程师和研究人员提供选型参考。Basilisk在性能和扩展性上表现突出,而STK在可视化与专业模块上更具优势。

weixin_30632089的博客 589

AG32VF407直流电流采集仪设计:从1uA到10A宽范围采样与FPGA加速方案

本文详细介绍了基于AG32VF407芯片的直流电流采集仪设计方案,实现了从1uA到10A的宽范围采样。方案采用低噪声电源、精密运放调理、高速比较器自动档位切换及高精度ADC同步采样,并重点阐述了利用AG32VF407片内FPGA实现硬件加速以提升性能的架构思路,为精密电流测量提供了完整的硬件与FPGA加速解决方案。

weixin_33245447的博客 312

设计模式之单例模式(Singleton Pattern)

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决:一个全局使用的类频繁地创建与销毁。何时使用:当您想控制实例数目,节省系统资源的时候。如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。关键代码:构造函数是私有的。

weixin_42294716的博客 1398

抖音 X-Gorgon 加密算法逆向与 Python 爬虫实战(2026 最新版)

抖音(TikTok 国内版)作为日活超 8 亿的超级 App,其反爬体系在国内互联网中属于顶级难度。核心签名参数X-Gorgon和X-Khronos是几乎所有业务接口(视频详情、评论、搜索、用户主页)的“通行证”。没有正确的 Gorgon 签名,服务器直接返回403或。市面上的教程大多停留在2023 年之前的 V4 版本,而抖音在 2025 年底全面升级到了V6 协议,算法结构、加密常数、混淆方式全部重构。

2201_76125261的博客 357

23种设计模式之单例模式(Singleton Pattern)【设计模式】

📒单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式主要用于控制资源的访问,确保某些类只有一个实例,并且这个实例能够被全局访问。

李赛赛的专栏 1104

SpringBoot4+Java21前后端分离架构项目脚手架

本文介绍了基于SpringBoot 4和Java 21的前后端分离项目架构方案。主要内容包括:1)采用Spring Security 7实现JWT无状态认证和RBAC权限控制;2)后端使用MyBatis-Plus简化数据库操作,前端采用Vue3+Pinia组合;3)详细的项目结构设计,推荐按业务模块分包;4)核心依赖配置和架构设计图,涵盖认证授权流程。该方案结合最新技术栈,提供了生产级的全链路实现,特别适合需要快速构建现代化Web应用的项目。

Hello, New World! 424

高通开发系列 - Bootloader之lk匹配dtb和dtbo中msm-id和board-id的知识

lk匹配dtb和dtbo中的msm-id和board-id等知识

fulinux的博客 4251

设计模式:单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是一种创建型设计模式,它的核心思想是:保证在一个进程中,某个类仅有一个实例,并提供全局访问点。

TechNomad的博客 1456

2026年03月CCF-GESP编程能力等级认证C++编程一级真题解析

本文收录于专栏《。订阅后可阅读专栏内所有文章。

人生就是一个不断学习的过程 343

设计模式——单例模式(Singleton Pattern)

设计模式——单例模式(Singleton Pattern) 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在有些场景中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,且该类能自行创建这个实例,这就是所谓的单例模式 文章目录设计模式——单例模式(Singleton Pattern)单例模式的优缺点优点缺点单例模式的应用场景单例模式与静态类的区别常见的7种实现方式1.饿汉模式2.懒

qq_42498542的博客 834

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

实践GoF设计模式:Singleton Pattern 单例模式

前言 我们在开发项目中,经常会遇到这种情况,为了节约所拥有的系统资源或数据的一致性时,需要保证系统中的某个类中有且只有唯一的一个实例,而且在其创建成功之后,我们将不能再次创建同类型的其他对象,也就是所有的操作都要以这个唯一的实例为中心,所以为了保证对象所具有的的唯一性,单例模式成为我们所具备的方法 概念 ● 设计模式中单例模式是最为简单的形式之一,而且是使用最广泛的设计模式之一,其目的是为了将类的一个对象成为系统中的唯一实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享 ● 要想实现这一点,可以

m0_70748458的博客 402

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

设计模式总结之Singleton Pattern(单例模式)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

cooldragon的专栏 4858

golang mysql单例模式_GoLang 设计模式之单例模式 (Singleton Pattern)

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设 计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。???? 单例模式 (Singleton Pattern)现实世界的例子:一次只能有一个国家的总统。简单来说:确保只创建特定类的一个对象。单例模式实际上被认为是反模式,应该避免过度使用它。它不...

weixin_39924573的博客 282

设计模式——单例模式(Singleton Pattern)+ Spring相关源码

确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。避免一个全局使用的类频繁地创建与销毁。

码鹿的记录 367

【Java设计模式】之 单例模式(Singleton Pattern)模式 饿汉式单例模式 vs 懒汉式单例模式

什么是设计模式? 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索,设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,"套路”。 设计模式的分类: ① 创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 ② 结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 ③ 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、

weixin_46081857的博客 419

设计模式之单例模式(Singleton pattern)

单例模式是一种常用的软件设计模式,通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 看代码: 1 namespace SingletonPattern 2 { 3 public class Singleton 4 { ...

145

设计模式---单例模式(DesignPattern_Singleton)

DesignPattern_AbstractFactory 摘录自:设计模式与游戏完美开发 工程GitHub SINGLETON—俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Singleton,她们只要说道“老公”,都是指的同一个人,那就是我(刚才做了个梦啦,哪有这么好的事) 单例模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例...

su9257的博客 145

JavaScript 设计模式之-单例模式(Singleton Pattern)

面试了很多简历写着前端5,6年高级前端工程师,大部分设计模式都说不明白,其实不要把设计模式想的很难,其实是一种思想,我一起搞iOS,也搞前端,设计模式原理都是一样的,写法就不差不多,只要搞清楚他的概念和使用场景就理解很容易 什么是单例模式? 规定一个类只有一个实例,并且提供可全局访问点; 单例模式的有哪些使用场景? 就APP 开发来说,单例模式还是比较常用的,比如弹窗组件,通过全局单例维护相关状态,如果每次创建一个新的对象,有些场景会多个弹窗叠加。 还有定位,或者网络请求,都是使用单例进行封装的。 例如.

冷胜任 的专栏 526
上一篇: 设计模式之观察者模式
下一篇: 设计模式之代理模式
西红柿丶番茄
博客等级 码龄10年 21粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值