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

Ollama模型路径迁移实战:Windows/Mac/Linux三系统保姆级教程(附常见问题排查) 本文提供了一份详细的Ollama模型路径迁移教程,涵盖Windows、macOS和Linux三大操作系统。针对默认安装路径占用系统盘空间的问题,文章指导用户如何安全移动模型文件、配置环境变量、重启服务,并附有迁移后的验证步骤与常见问题排查方法,帮助用户高效管理本地AI模型存储。 阅读详情
我们知道懒 汉式的实现 是延迟加载(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   方法的一个弊端,代码的性能比较糟糕。这种简单且粗粒度的方法能确保线程安全性,但是不能同时处理多个请求,付出的代价很高。

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













Rocky Linux 8.10下用cephadm快速搭建Ceph集群(附华为云镜像源配置) 本文详细介绍了在Rocky Linux 8.10操作系统上使用cephadm快速部署Ceph集群的实战指南,包括环境准备、系统配置、华为云镜像源优化、集群初始化及节点扩展等关键步骤。通过配置华为云镜像源,显著提升部署效率,适合企业级存储解决方案的需求。 阅读详情

相关推荐

echarts实现折线图上下限区域展示

效果图: 画这种区域中主要是利用了series的两个属性: 思路:上下限都画上区域,然后折线利用图形透明度隐藏,给上区域加上颜色,给下区域加上白色(echarts图背景是啥色,就加啥色) lineStyle: { opacity: 0 }, // 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形 areaStyle: { color: 'rgba(0,122,255,0.1)' }, // 填充的颜色 我的需求是最大天数、最小天数、

小太阳的博客 1万+

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

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

weixin_45237107的博客 219

从半导体物理到实战:手把手教你测量MOS管体二极管的Vf和Trr

本文深入探讨了MOSFET体二极管的关键参数测量方法,重点讲解了正向压降(Vf)和反向恢复时间(Trr)的测量原理与实战步骤。通过搭建测试平台,使用万用表和示波器等工具,手把手指导如何量化这些影响开关损耗和效率的核心参数,并对比分析了硅基与碳化硅(SiC)器件在体二极管性能上的显著差异。

n7o8p的博客 339

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

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

王京伟的博客 581

H3C防火墙旁路部署实战:网关迁移到防火墙后,如何配置DHCP和VLAN间隔离策略?

本文详细介绍了H3C防火墙旁路部署实战,重点讲解网关迁移到防火墙后的DHCP配置和VLAN间隔离策略。通过实际案例和配置示例,帮助网络工程师解决传统核心交换机架构的性能瓶颈和安全管控问题,实现精细化访问控制。

weixin_42549451的博客 414

GOM引擎单机传奇架设全攻略——从DBC2000配置到登录器生成

本文详细解析了使用GOM引擎架设单机传奇的完整流程,从DBC2000的安装配置、服务端部署、引擎控制器设置,到登录器生成与客户端补丁放置。文章重点解决了单机架设中的常见问题,如数据库路径配置、IP地址设置及Key.lic文件处理,旨在帮助玩家快速搭建稳定的个人游戏环境,体验GM乐趣。

weixin_28318011的博客 627

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

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

lanzhizhuxia的专栏 8649

基于STM32单片机智能循迹小车毕业设计

本文介绍了一种利用STM32F103C8T6单片机为控制核心,结合多种传感器以及PID算法实现循迹避障功能的智能小车。随着我国高科技水平的不断提高和工业自动化进程的不断推进,智能小车被广泛应用于各种玩具和其他产品的设计中,极大地丰富了人们的生活。本次设计利用反射式红外光电传感器探测路面黑线实现小车循迹,利用超声波测距传感器探测路径上的障碍,控制小车自动避障,整个系统具有自动循迹、自动避障、速度检测和无线遥控功能。其中,控制部分采用STM32F103C8T6单片机,STM32F103C8T6单片机是一

qq_48771816的博客 3974

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

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

weixin_43106895的博客 1675

华为OD 面试手撕代码真题【岛屿的周长】

0代表水,1代表陆地,岛由陆地组成且岛内不允许有湖,让你求岛的周长。

MISAYAONE的博客 8414

ICC2:postmask ECO参考脚本

更多学习内容请关注「拾陆楼」知识星球。

m0_61544122的博客 882

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

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

weixin_48178004的博客 976

matlab数学建模练习(2)练习电子科技大学数学实验

【代码】matlab数学建模练习(2)练习电子科技大学数学实验。

c_wrj_的博客 1435

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

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

qq_41854180的博客 1601

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

为什么单例模式中的懒汉模式要用双重校验锁

为什么单例模式中的懒汉模式要用双重校验锁 首先懒汉模式的用双重校验锁的代码如下: public class ST { private static volatile ST st = null; private ST() { } public static ST getInstance() { if (st == null) { synchronized (ST.class) { try {

Triple_star的博客 1420

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

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

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

努力进阶的小菜鸟 2810

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

懒汉模式-双重同步锁机制

懒汉模式 是在使用的时候才会生成对象 public class Singleton{ private static Singleton singleton = null; //私有化构造函数,不能从外部生成 private Singleton(){ } public static Singleton getSingleton(){ if(...

Minstrel的博客 2529

Singleton单例模式-【懒汉式-加双重校验锁&防止指令重排序的懒汉式】实现方案中为什么需要加volatile关键字

前提知识点:volatile可以保证可见性+防止指令重排序,synchronized可以保证可见性+防止指令重排序+原子性。 也即是说volatile是synchronized的功能子集,我们知道在【懒汉式-加双重校验锁】的单例模式实现中已经使用了synchronized关键字,那为什么还需要加volatile关键字呢 回顾【懒汉式-加双重校验锁&防止指令重排序的懒汉式】 public...

明月专栏 2436

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

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

bkdl047的博客 1286

懒汉式单例--双重检测锁实现线程安全

Football2.java /** * 懒汉式单例 * 用的时候再创建一个对象,线程不安全 * @author Administrator * */ class FootBall2 { private static int count; private static FootBall2 fb; private FootBall2(){ ...

andQ的博客 860

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

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

zfeiyu的博客 489

懒汉式单例模式的方法及改进

/** * Created by Mr.Wang on 2019/2/17. */ public class LazyMan { private static LazyMan lazyMan = null; private LazyMan(String dateTime){ System.out.print("....dateTime...Do Someth...

厚积薄发 252

单例模式的八种实现--应该是你见过的最全的单例模式实现啦。

一般说到单例模式,老铁们,都是知道老师讲的:饿汉式,饱汉式,双重旋锁式。然后呢,这些个实现,老师讲的不全,马马虎虎,觉得给你说一下,就够用啦。但是,你实际被问到的时候,就觉得,当年老师说的全的,是OK的,其实不是的。老师讲的不全,毕竟老师少有很讲究刨根问底的。 在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控...

请叫我大师兄 1万+

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

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

m0_37121708的博客 889

单例模式 (懒汉,饿汉,双重校验锁)

单例模式什么是单例模式? 单例保证一个对象JVM中只能有一个实例,常见单例懒汉式、饿汉式 什么是懒汉式,就是需要的才会去实例化,线程不安全。 什么是饿汉式,就是当class文件被加载的时候,初始化,天生线程安全。 懒汉式 代码 package designpatterns23.singleton; /** * 单例模式的作用:保证一个类在项目中有且只能有一个实例 * 在调用的时候在去初始化天...

lizhen1114的博客 2570

单例模式

保证该类只有一个对象,适用于对于配置文件的加载的情况。分为饿汉单例和懒汉单例两种//饿汉模式class Singleton1{    private static Singleton1 singleton=new Singleton1();private Singleton1(){};public static Singleton1 getInstance(){return singleton;}...

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值