关于单例(Singleton)模式实现方式的反思

C++单例模式深度解析:懒汉式与饿汉式的实现与线程安全 单例模式是软件设计中确保类只有一个实例并提供全局访问点的创建型模式。其核心原理是通过私有化构造函数和静态成员控制实例化过程,实现资源的统一管理与状态共享。该模式的技术价值在于优化资源使用、避免重复创建开销,并保证全局状态的一致性。在C++工程实践中,单例模式广泛应用于配置管理、日志系统、线程池及数据库连接池等场景。针对多线程环境下的线程安全挑战,开发者需在懒汉式的延迟初始化与饿汉式的启动即加载之间权衡,并合理运用互斥锁、双重检查锁定及std::call_once等同步机制,以规避静态初始化顺序与对象析构难题 阅读详情
    大家都知道单例模式,也知道实现的方法,最近看到几个网友推荐的文章,仔细思考了一下,发现我以前的想法是有问题的。

    先看我一直使用的单例代码样例:
  1. /**
  2.  * 一段我一直使用的单例实现的代码。
  3.  * 
  4.  * @author 赵学庆,Java世纪网(java2000.net)
  5.  * 
  6.  */
  7. public class Singleton {
  8.   private static volatile Singleton instance;
  9.   private Singleton() {
  10.   }
  11.   public static Singleton getInstance() {
  12.     if (instance == null) { // 1
  13.       synchronized (Singleton.class) { // 2
  14.         if (instance == null) // 3
  15.           instance = new Singleton(); // 4
  16.       }
  17.     }
  18.     return instance;
  19.   }
  20. }

系统先判断是否已经初始化(1),
如果没有初始化则进入同步(2),
然后再次判断是否已经初始化(3),
如果还是没有则初始化一个(4).

    系统考虑了多CPU问题,使用了 volatile 这个修饰符。 我自认这个代码没有任何问题,但是:??

    一个文章里说到的奇怪的执行顺序引起了我的注意,我来说明一下2个线程的执行过程:

    线程1这行到了(4),此时系统需要做的事情是给Singleton分配内容,然后进行初始化,可是对instance的赋值操作是在类初始化之前完成的。那没就会出现

    线程2 此时拿到了CPU,此时判断instance 已经不再是null,于是他使用了这个已经分配了内存,但没有初始化完毕的类,然后造成运行结果异常。

    这个问题我想还是很有可能的,毕竟我们无法保证JVM一定在类已经完全初始化完毕之后再赋值给instance。因为这样做,系统要额外分配一个变量用来临时指向新分配的内存,完成所有的初始化之后再把内存指向instance。而正常的理解,肯定是不会额外的浪费这个变量的(希望我的猜测是错的,我宁可我是错的)。


下面是我再次搜索并整理的更安全的初始化方法,大家参考看看:

第一种,使用静态初始化
  1. class Singleton {
  2.   private static volatile Singleton instance = new Singleton();
  3.   private Singleton() {
  4.   }
  5.   public static Singleton getInstance() {
  6.     return instance;
  7.   }
  8. }
第二种,使用 静态 内部类进行初始化
  1. class Singleton {

  2.   static class SingletonHolder {
  3.     static volatile Singleton instance = new Singleton();
  4.   }
  5.   private Singleton() {
      }

  6.   public static Singleton getInstance() {
  7.     return SingletonHolder.instance;
  8.   }

  9. }
    有评价说,第二种更加的安全。我能力有限,实在不能窥透他们的区别,我只能按照保守的估算,在我以后的代码里,全部用第二种方法。

    另外,楼下网友提供的用临时变量的方法,你可以参考我的参考文章,里面讲述了理由。在一些编译器优化时,会把它优化掉,造成并不能达到我们要的结果。也就是编译器会认为你的那个临时变量是多余的。

    期待牛人能给个更准确的说法。


参考文章:
1 解析 Java 类和对象的初始化过程
2 Java中的模式 --单态
3 The "Double-Checked Locking is Broken" Declaration


Laravel框架中运用单例模式 阅读详情

相关推荐

Laravel开发-singleton-pattern

Laravel开发-singleton-pattern 帮助程序包来实现单例类。

laravel 简单聊聊singleton的实现过程

文章目录场景解析 场景 最近在看laravel request lifecycle;laravel 在完成Illuminate\Foundation\Application的实例化之后,接着就注册了三个Kernel的singleton ; 那么singleton 完成了什么操作了呢? 下面就以$app->singleton(Illuminate\Contracts\Http\Kernel:...

cominglately的博客 4310

京东商品多维特征提取:基于时空大模型的实时库存预测接口设计

在电商行业,库存管理是供应链的核心环节之一。库存水平过高会导致资金占用、仓储成本增加,而库存水平过低则可能引发缺货风险,影响客户满意度和平台声誉。京东作为中国领先的电商平台,拥有海量的商品数据和复杂的业务场景,传统的库存预测方法难以应对市场动态变化和业务需求。时空大模型作为一种融合时间序列分析和空间特征提取的前沿技术,能够捕捉商品多维特征在时空维度上的变化规律,为实时库存预测提供更精准的决策依据。

FB13713612741的博客 954

Laravel框架源码设计模式分析(一)——单例模式

单例模式在laravel中使用的非常多,有一些对象我们只需要一个,不希望造成浪费,就就会用到单例,在源码中用到singleton()这个放弃,其实就用到单例模式了。比如线程池(threadpool)、缓存(cache)、对话框、处理偏好设置和注册表(register)对象等等。 以下是分析Container中使用到的单例模式。 Laravel框架中的大部分功能都是在容器中实现的,是一个用于管理类依赖和执行依赖注入的强大工具,而它最常用的功能就有服务提供者。...

weixin_46121939的博客 1790

准静态电磁场

叠加法 缺点:对于连续分布的电荷,叠加法的计算比较困难 虚位移法 概念 广义坐标:确实系统中导体形状、尺寸与位置的一组独立几何量。 广义力:企图改变某一广义坐标的力。 功:广义力乘上由它引起的广义坐标的改变量。 公式 ...

qq_35912930的博客 1860

PyTorch、Torchvision、Torchaudio历史版本whl文件下载地址、版本对应关系与离线安装全攻略

本文详细解析了PyTorch、Torchvision和Torchaudio历史版本whl文件的下载地址、版本对应关系及离线安装全攻略。针对无网络环境下的安装挑战,提供了官方whl文件获取路径、版本匹配技巧和完整安装流程,帮助开发者高效解决兼容性问题,确保深度学习环境的稳定部署。

weixin_31960565的博客 379

laravel使用单例模式实现百度审核功能(使用全程)

简化代码逻辑:如果多个对象需要访问同一个共享资源时,如果不使用单例模式,则需要在应用程序的多个模块中分别创建和管理这个共享资源,这会增加代码的复杂度和难度,降低程序的可维护性。高效快速:百度审核的审核速度非常快,可以在几秒钟内对大量的内容进行审核。提高用户体验和品牌形象:通过使用百度审核,可以快速发现并处理违法违规信息,保障用户的体验和品牌的形象,提高了公司的公信力和市场竞争力。提高程序的性能:如果对于某些需要频繁创建和销毁的对象,使用单例模式可以避免频繁的创建和销毁,从而提高程序的性能。

windowserim的博客 558

拖动无标题栏的cef3窗口

拖动嵌入了cef3的无标题栏win32窗口,本质上就是拖动子窗口移动父窗口这么个事情,这个在自己创建窗口的程序上处理非常简单,cef封装较多,想修改的完善点步骤较多。         cef所用版本3.2623。         就用cefclient来做测试工程,首先建议在cefclient_win.cc的RunMain函数中的app = new ClientAppRenderer();前面

loveyong1990的专栏 6161

【Laravel 设计模式-----------单例模式】

单例模式,最初我自己的理解是,一个PHP文件即为一个类,不要用多个类放在一个PHP文件。这是极其的片面,并没有理解其中的缘由,单例模式的好处也没有理解。 在此集百家之所长,汇聚前人们的理解。哈哈,让我学习了一些。 单例模式好处是:对象不可以外部实例化,只能实例化一次,节省资源。 实现方式: 该实现方式引用于 简书 解读: 声明一个类的私有或者保护的静态变量...

余生不长,善待自己。 2189

AHB总线协议

1. 简介         AHB总线规范是AMBA总线规范的一部分,AMBA总线规范是ARM公司提出的总线规范,被大多数SoC设计采用,它规定了AHB (Advanced High-performance Bus)、ASB (Advanced System Bus)、APB (Advanced Peripheral Bus)。AHB用于高性能、高时钟频率的系统结构,典型的应用如ARM核与系统内

ivy_reny的专栏 8万+

C# 操作Excel的时候,出现"被呼叫方拒绝接受呼叫的异常"的解决方案(参考官方给出的解决方案)

首先官方有对这个错误给出解释和解决方案,连接如下: https://docs.microsoft.com/zh-cn/previous-versions/ms228772(v=vs.120)#%E5%8F%AF%E9%9D%A0%E7%BC%96%E7%A8%8B 简单来说,貌似是线程问题,我猜。。。 之前我尝试着在代码中添加 Thread.Sleep(1000); 来进行解决,这种办...

Ck_Max的博客 5770

Singleton_模式_关于单例(Singleton)模式实现方式的反思

<br /> 简介摘要: 大家都知道单例模式,也知道实现的方法,最近看到几个网友推荐的文章,仔细思考了一下,发现我以前的想法是有问题的。 先看我一直使用的单例代码样例: /** * 一段我一直使用的单例实现的代码。 大家都知道单例模式[mo shi],也知道实现的方法[fang fa],最近看到几个网友推荐的文章,仔细思考了一下,发现我以前的想法是有问题[wen ti]的。 先看我一直使用的单例代码[dai ma]样例: /** * 一段我一直使用的单例实现的代码

上班搞IT,下班搞ITF。 1291

黑猫带你学eMMC协议第33篇:eMMC CQE功能介绍——一种模仿UFS命令队列的发送机制

本文详细介绍了eMMC协议中的Command Queuing Engine (CQE)及其相关功能。CQE是eMMC 5.1版本引入的新特性,旨在通过硬件处理命令队列,简化软件代码的编写。文章首先介绍了CQE的基本概念,包括其与Host Controller Interface (HCI)的区别,以及CQE如何通过Task Descriptor List (TDL)管理任务。接着,文章详细描述了CQE如何发送命令和数据给eMMC,并解释了Task Descriptor和Transfer Descriptor

黑猫奥利奥的博客 982

Singleton实现的反思

   Singleton可算是最简单的模式,本文记述小鸡射手遇到的问题及反思。     对于Singleton,小鸡射手想能不能:    1. 将private static成员变量直接声明为Singleton类?    2. 将要调用的方法直接声明为static?     在项目中,采用VC++按方式1实现Singleton类,编译、链接一切OK。运行时却出现了内存方面的exception,经调

1337

【异常】‘build.plugins.plugin.version‘ for org.apache.maven.plugins:maven-resources-plugin is missing

maven-compiler-plugin 插件版本信息没有指定导致了错误提示如下字面意思就是没有指定版本信息。

奶爸的编程之路,也就一周冷个三天 4600

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Java设计模式实战:从单例到策略,代码实现与避坑指南

设计模式是软件工程中解决常见问题的经典方案,其核心在于通过封装变化来提升代码的灵活性和可维护性。从原理上讲,设计模式遵循开闭原则、依赖倒置等设计思想,将易变的部分抽象隔离,使系统更易于扩展。其技术价值在于帮助开发者应对复杂多变的业务需求,避免代码腐化,提升团队协作效率。在应用场景上,无论是创建型模式如单例模式管理全局配置,结构型模式如适配器模式整合遗留系统,还是行为型模式如策略模式实现动态算法替换,都是工程实践中的高频需求。本文聚焦于Java语言,通过工厂模式、适配器模式等具体实现,结合单例模式的双重检查锁

weixin_34319111的博客 418

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

设计模式不是八股文:单例、工厂、适配器、观察者的工程实践指南

设计模式是面向对象编程中应对常见结构问题的成熟解决方案,其本质在于解耦、封装变化与提升可维护性。从单例模式对资源生命周期的可控管理,到工厂方法对对象创建逻辑的隔离;从适配器模式在异构系统(如VMware驱动、KM-Test环回适配器)集成中的桥接作用,再到观察者模式在Qt信号槽、配置变更通知等场景下的松耦合事件分发——这些模式共同构成软件架构的‘基础语法’。掌握它们的关键不在于记忆定义,而在于识别代码中的坏味道信号:重复分支、过度依赖、全局状态滥用、职责混杂与测试困难。本文聚焦C++/Qt/Java真实工程

weixin_30788619的博客 688

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jre9下载 jdk9

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

php 单例类可以被继承吗,php多子类继承的单例类实现方式

class Parents{protected $client;protected function __construct(){//一系列操作....$this->client = new $this->clientName();}public static function getInstance(){if (static::$ins === null){static::$ins ...

weixin_28869849的博客 258

Python设计模式深度解析:原理与实现详解

本文系统梳理了Python中23种GoF设计模式,分为创建型、结构型和行为型三大类。创建型模式如单例、工厂方法等解决对象创建问题;结构型模式如适配器、装饰器等处理类与对象组合;行为型模式如观察者、策略等管理对象间交互。特别指出Python动态特性使某些模式实现更简洁,如策略模式可直接使用函数。文章采用表格对比各模式复杂度、适用场景及优势,并给出持续学习建议,强调结合Python特性灵活应用设计模式。

专注人工智能应用领域 1275

使用C++实现设计模式(连载): 第一回 Singleton 单例模式

又一次仔细读了刘未鹏写的《暗时间》,总结自己之所以在编程方面成长不理想的原因就是自己花在总结上的时间太少了,总是写过的代码和用过的模式很快就忘记了,有点过分依赖参考资料和Google. 因此,今天起陆续总结一下自己使用过的一些设计模式,不过由于C++设计模式方面的资料很少,我将坚持采用C++语言说明。 第一回:Singleton...

weixin_30323961的博客 79

关于枚举类的反思

  1.5以后的一个新特性就是枚举,在进入优快云前的这么久我都一直用的是1.4风格的代码风格,原来自己落后这么多年了.  后来火龙果问了一个问题,问题是这样的.  要求一个方法只能传入1-10的作为参数,不然的话,就会报错,不过不能是运行时报错,应该是编译报错.  当时不是很明白,后来在看Thinking in java 的过程中,看到了这样的一个类,才恍然大悟.   我们就来看

nihuajie05的专栏 717

设计模式-单例模式中的double-check

单例模式中的double-check 单例模式一般有两种模式:饿汉模式和懒汉模式 1.饿汉模式:程序启动的时候,由主线程创建一个对象实例。 2.懒汉模式: 程序启动的时候,不创建对象(NULL),如果有两个线程先后执行if(NULL == ms_Singleton)获取对象,那么将创建两份实例。要解决该问题,需要上锁。 经典的单例模式代码如下: template <typename T&g...

suyinfan的博客 688
上一篇: JFrame窗口关闭时,进行再次确认的实现
下一篇: 生成不重复随机数的一种算法
老紫竹
博客等级 码龄19年 1万+粉丝 1252原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值