【单例深思】懒汉式改进版与内置锁

Diffusion:如何从噪声中生成清晰图像 扩散模型是当前AI图像生成领域的核心基础,如Stable Diffusion、DALL·E等热门模型均采用该技术。其原理分为训练和推理两个阶段:训练时通过逐步加噪图片,让AI学习如何去除噪声;推理时则从随机噪声出发,结合文本提示逐步去噪生成清晰图像。模型架构通常包含文本编码器、生成模型(如U-Net)和解码器三部分,通过多轮迭代将低维潜在空间表示转化为最终图像。这种技术模拟了艺术家从混沌中雕琢作品的过程,实现了从随机噪声到目标图像的智能生成。 阅读详情
我们知道懒 汉式的实现 是延迟加载(Lazy Loading),但是不是 线程安全 的, 下面我们深入研究下为什么。

懒汉式的实现如下:

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

相比于饿汉式实现,懒汉式是 线程安全的,因为懒汉式中的类成员 singleton 在声明时没有立即使用 new   关键字实例化,而是在 getInstance() 方法里面才使用 new   进行实例化,此时 Singleton 类的初始化不会实例化 singleton 。
只有当外部调用使用静态的 getInstance() 方法时, 类成员 singleton 才会被分配内存实例化,因此就达到了延迟加载的目的。
如有疑问,可参照 【单例深思】饿汉式与类加载  

接下来我们重点来看看懒汉式为什么不是线程安全的?

在多线程情况下,如果 singleton 还没有被实例化,此时它的值为null,如果这时有可能多个线程同时进入 getInstance() 方法中,同时执行   if  ( singleton  ==  null ) 这行代码,得到的结果都为true,于是这些线程都会使用 new  Singleton(); 为 singleton 分配内存,这时 singleton   就不是单例了,所以 懒汉式 就不是线程安全的。

懒汉式改进版解决了这个问题,其实现如下:

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

其只改进了一个地方,就是使用关键字 synchronized   来声明 getInstance() 方法。这个关键字的作用就是给 getInstance() 加锁,加锁后这个方法就具备了原子性,每次只能由一个线程执行这个方法,其他请求线程则会被阻塞,直到活跃线程执行完毕。如果每次只有一个线程执行这个方法中的代码,那么我们上面讨论的线程安全问题就不复存在了,不会出现创建多个实例的情况了。

Java 提供了一种内置的锁机制来支持 原子性( 一组语句作为一个不可分割的单元被执行 ): 同步代码块(Synchronized Block),同步代码块包括两部分,一个作为 锁的 对象引用,一个作为由这个锁保护的 代码块。以关键字 synchronized   来修饰的方法就是一种横跨整个方法体的同步代码块,其中该同步代码块的锁就是方法调用所在的对象。静态的 synchronized   方法以Class 对象作为锁。
synchronized(lock){
        //由锁保护的代码块
}  
每个Java对象都可以用做一个实现同步的锁,这些所被称为内置锁。
线程进入同步代码块之前会自动获得锁,并且在退出同步代码块时自动释放锁,而无论是通过正常的控制路径退出,还是通过从代码块中抛出异常退出。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。

Java 的内置锁相当于一个互斥体(或互斥锁),这意味着最多只有一个线程能持有这种锁,当线程A尝试获取一个由线程B持有的锁时,线程A必须等待或阻塞,直到线程B释放这个锁。如果线程B永不释放这个锁,那么A就永远等待下去。

懒汉式改进版中 getInstance() 方法是静态的 synchronized   方法,因此以 Singleton.Class  作为锁, 线程只有获得了这个锁才能执行 getInstance() 方法,因此保证了线程安全性。但是这个锁只有一个,意味着同一时刻只能有一个线程执行该方法。如果这个单例很火,有很多线程需要获取它,那么就会影响单例的获取。这也是 synchronized   方法的一个弊端,代码的性能比较糟糕。这种简单且粗粒度的方法能确保线程安全性,但是不能同时处理多个请求,付出的代价很高。

这也就是双重检测锁实现出现的原因,通过缩小锁的粒度来增强活跃度,这将在下篇文章中详细讨论。













Remosaic 算法 在 4in1 传感器中,相邻的 4 个同色像素(如 4 个红色、绿色或蓝色像素)合并为 1 个“超级像素”,以提升低光环境下的感光能力。例如,在 RGGB 排列中,每个 2x2 的 Quad 单元需要恢复为 4 个独立的 R、Gr、Gb、B 像素1。:传感器通过硬件级 Remosaic 直接输出 4800 万像素的原始数据,每个像素独立记录颜色信息,解析力更高2。:传感器仅输出 1200 万像素数据,再通过软件算法插值放大到 4800 万像素,实际解析力无本质提升2。的原始数据转换为传统。 阅读详情

相关推荐

Unity简单操作:PostProcessing的使用

Postprocessing是一个unity2018版本的集成后期插件,有了这个插件,之后用unity开发时,后期调整颜色、光晕等会很方便。 目录 新建一个postprocessing profile(配置文件)。​ 参数说明: 新建一个postprocessing profile(配置文件)。 在主相机下加一个组件PostProcess Layer。 注意:需要将相机的Layer层设置与Post Process Layer 下的Volume blending(体积混合)...

weixin_39114763的博客 7368

单例模式——懒汉式的改进

单例模式——懒汉式的改进 在之前的单例模式中,懒汉式存在线程不安全的情况,在本篇中加以改进。 /** * 使用同步机制将单例模式中的懒汉式改写成线程安全的 */ public class BankTest { } class Bank{ private Bank(){ } public static Bank bank = null; //Object o = new Object(); public static Bank getInstance(){

weixin_45237107的博客 219

FLUENT UDF编译及蒸发冷凝相关问题

蒸发冷凝与相间传质

weixin_48029137的博客 1万+

不使用锁解决懒汉式单例线程安全问题

先来看常见的使用锁解决懒汉式单例线程安全问题的例子 /** * @author ZJX * @date 2021/10/8 * @description */ public class LazySingleton { public static User user; public static User superUser(){ if(user == null) { //这里可以不直接锁User类,可以在当前类添加个变量,锁变量。

qq_43527397的博客 309

别光看手册!手把手教你用SGM2036 LDO设计一个稳定3.3V转1.8V的MCU供电电路(附PCB布局避坑指南)

本文详细介绍了如何使用SGM2036 LDO设计一个稳定的3.3V转1.8V的MCU供电电路,包括需求分析、芯片选型、外围器件计算、PCB布局避坑指南及实测验证。通过实际案例和计算示例,帮助工程师快速掌握LDO应用技巧,确保系统电源稳定可靠。

weixin_42548893的博客 505

麒麟操作系统提示“默认密钥环已上锁”的解决办法

麒麟操作系统提示“默认密钥环已上锁”的解决办法

太极淘的博客 1万+

单例模式---懒汉式的优化

单例模式中最重要的思想是:构造器私有,因此能保证我们的内存中只有一个对象。 单例模式分为懒汉式和饿汉式 1.饿汉式:顾名思义,很饿,上来就吃。 package cn.com; //饿汉式单例,在程序运行时,无论是否需要 都会创建对象,因此 可能会浪费空间 public class HungryMan { //构造器私有,无法new 这个对象 private HungryMan() { } private static HungryMan HUNGRY = n

王京伟的博客 581

Android系统修改驱动固定USB摄像头节点绑定前后置摄像头

Android系统中usb摄像头节点会因为摄像头所接的usb口不同或者usb设备识别顺序不一样而出现每次开机生成的video节点不一样的问题。由于客户app调用摄像头时,需要固定摄像头的节点。因此需要针对前面的情况做处理。

Android系统开发笔记 2250

设计模式--单例模式(三)改进型懒汉式

本文是设计模式学习笔记的第二篇文章,主要分析的是单例模式。包括懒汉式,饿汉式,登记式,以及懒汉式的改进型,还有一个关于读取propertoes配置文件的实例。这是第三节,本来想把这这节和上一节放在一起的,但是内容太多了,于是拆成了2次上一节分析了在数量上有所扩展的单例模式--登记式。这次我们来看一下在第一节中提到的,具有懒汉式和饿汉式俩种特点的解决方案。 这个解决方案的名字是Lazy initi

lanzhizhuxia的专栏 8649

二极管钳位电路、限幅电路和检波电路Multisim电路仿真

本文系统介绍了二极管钳位、限幅和检波三种基础电路的工作原理及Multisim仿真验证。钳位电路通过电容-二极管配合实现波形整体平移,将波峰或波谷固定在指定电压;限幅电路利用二极管导通特性削除信号超出设定阈值的部分;检波电路则通过半波整流和电容滤波从调幅波中提取音频信号。三种电路均通过Multisim仿真验证了理论分析结果,展示了二极管在信号处理中的关键作用。这些基础电路广泛应用于信号调理、电平保护和通信解调等领域。

XU157303764的博客 1120

AI智算-K8s+vLLM & Ray:DeepSeek-r1 671B 满血版分布式推理部署实践

自从上次发布 【AI-智算】K8s+SGLang实战:DeepSeek-r1:671b满血版多机多卡私有化部署全攻略] 文章后,本次将演示另一个主流推理引擎工具——vLLM,结合K8s、LWS、Ray、Volcano等技术栈,部署DeepSeek-r1 671b 满血版分布式推理集群,并对比其与SGLang推理引擎的性能表现。

Kason_iWiki 1825

重新认识单例模式,饿汉、懒汉、加锁、双重检锁、静态内部类

今天我们来重新认识下单例模式,虽然单例模式是Java中最简单的设计模式,但是实现方式涉及到了很多Java知识,下面我们重新学习下 饿汉式 public class Singleton { private static Singleton singleton = new Singleton(); private Singleton() { } public static Singleton getInstance(){ return singlet

kl_Dreaming的博客 334

高通拨号流程介绍

本文介绍了高通平台(如SDX55)中APSS(A7处理器)与ModEM(Q6处理器)间的通信机制。

四儿家的小祖宗的博客 1067

【单例模式】

如果要保持懒汉式的特性,静态内部类方式是最推荐的,因为它简单、高效、线程安全。如果需要性能优化,可以使用双重检查锁,但要确保 instance 使用 volatile 关键字修饰。

m0_48431422的博客 1001

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

设计模式-单例模式

单例模式是一种常用的设计模式,并且是面试中常问的一种设计模式,这篇文章就整理一下本人学习到的几种单例模式的设计 1、饿汉式 饿汉式,顾名思义就是一上来就创建单例实例。 class HungerSingleton{ //类加载时就实例化 private static final HungerSingleton instance= new HungerSingleton(); //构造函数私有化 private HungerSingleton(){ }

TT_130616的博客 690

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

懒汉式和饿汉式单例模式以及解决单例的线程不安全

懒汉式和饿汉式是两种常见的单例模式实现方式,它们分别在不同情况下进行单例对象的初始化。

weixin_43106895的博客 1675

efm32 入门.pdf

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

线程同步锁:隐式synchronized,显式lock,懒汉设计模式加锁,死锁

1.有五个人同时过一个独木桥,一个独木桥同时只能允许一个人通过。每一个人通过独木桥的时间是随机在 [5,10] 秒,输出这个独木桥上每一个人的通过详情, 例如:张三开始过独木桥了… 张三通过独木桥了! public class Test { public static void main(String[] args) { Bridge t = new Bridge(); Thread t1 = new Thread(t, "张三"); Thread t2 = new Thread(t, "李四

Echoxxxxx的博客 481

Java的懒汉式双检锁单例模式

首先回忆一下,Java中的单例模式有两种,俗称“饿汉式”和“懒汉式”。懒汉式的线程问题可以通过加同步锁来解决,但是上面的懒汉式的代码的性能有点不好,同步锁加在了方法上面,如果实例之前已经初始化完成,每次调用方法都会去访问到同步锁,性能开销比较大,这个时候实际上不在需要加锁了,直接把实例化好的对象返回就可以了。这就引出了下面要说的双检锁,它其实是对懒汉式的一个优化。

weixin_48178004的博客 976

设计模式 ——【单例模式】

单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一...

Janson_Lin 642

单例模式实现,懒汉式、饿汉式、同步锁、双重检查锁

单例模式(Singleton) 单例模式定义 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态。

zbh1957282580的博客 1564

经典懒汉式双重检查 单例模式 加锁+volatile

package com.wangyue.springcloud.singleton; /** * 懒汉式单例(线程不安全) * 步骤: * ① 构造器私有化 * ② 定义一个静态变量存储对象, * ③ 定义一个获取单例的方法 双重检查,第二层检查加锁,同时需要volatile * */ public class Singleton05 { /** * 为什么要使用volatile * * 因为创建对象有三步操作

m0_37712622的博客 494

单例设计模式中的“懒汉式”单例,以及java的双重锁(锁块)

Java中的双重检查锁(double checked locking) 在实现单例模式时,如果未考虑多线程的情况,就容易写出下面的错误代码: public class Singleton { private static Singleton uniqueSingleton; private Singleton() { } public Singleton get...

bkdl047的博客 1286

单例模式之懒汉与饿汉与双重加锁机制

单例模式 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。 单例模式的实现 1.饿汉式 饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。 package com.it.sign; public class A2 { //定义一个该类的静态变量 实例化 public static final A2 a = new A2(); //构造方法私有化 private A

qq_41854180的博客 1601

今天主要写一个单例模式的常用四种写法(懒汉,饿汉,懒汉加锁,枚举)

今天主要写一个单例模式的常用四种写法(懒汉,饿汉,懒汉加锁,枚举) 设计模式有23种,常听到的有单例模式。 单例模式(解释):①模式:pattern:有规律的模式,或根据某种需求创造出的某种东西。 单例模式:一个类只有一个实例。 (一个软件只能打开一个窗口)(枚举是天生的单例模式<存放在同一个地址下 >) 注: (线程不安全,多线程可以创建两个线程) 实现: 1:不能被外部创建(pr...

m0_37121708的博客 889

单例模式懒汉式多线程锁定

package com.zfy.learn; /* * 单例模式 * */ public class SingleInstance { //volatile同步变量 static volatile SingleInstance instance; private SingleInstance(){ } public static SingleInsta...

zfeiyu的博客 489

手撕单例模式 (懒汉式 双重锁机制)

什么是单例模式? 单例模式就是一个类只能被实例化一次 ,更准确的说是只能有一个实例化的对象的类。(确保内存中只有一个的对象,该实例必须自动创建,并且对外提供) 优点 在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。 缺点 没有抽象层,因此扩展很难 职责过重,在一定程序上违背了单一职责 分类 懒汉式和...

努力进阶的小菜鸟 2810
上一篇: 【单例深思】饿汉式与类加载
下一篇: 【单例深思】双重检测锁与Java内存模型
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值