当前位置: 首页 > article >正文

java单例模式 懒汉式(双重检查锁)

/** * 懒汉式 方式6 双重检查锁 */publicclassSingletonLazy{// 1、私有构造方法privateSingletonLazy(){}// 2、在成员变量位置声明一个静态对象privatestaticvolatileSingletonLazyinstance;// 关键字volatile禁止指令重排序确保绝对安全// 3、对外提供静态方法获取唯一实例publicstaticSingletonLazygetInstance(){if(instancenull){// 提升性能第一次判断若instance不为空不进入抢锁阶段直接返回实例synchronized(SingletonLazy.class){if(instancenull){// 确保安全第二次判断抢到锁后再次判断是否为nullinstancenewSingletonLazy();}}}returninstance;}}synchronized (SingletonLazy.class) 是干什么的作用 这是一个互斥锁排他锁。因为 getInstance 是一个 static 方法它不属于任何对象实例而是属于类本身。所以需要锁住 SingletonLazy.class 这个类对象。比喻想象 synchronized 花括号 { … } 包裹的代码块是一个试衣间而 SingletonLazy.class 是这个试衣间唯一的钥匙。不管外面有多少人线程想进去同一时间只有一个人能拿着钥匙进去。其他人如果没有抢到钥匙就必须在门口排队等待Block直到里面的人出来并归还钥匙。2. 为什么抢到锁了还要做第二次判断**疑问“既然线程 A 进去了线程 B 就进不去那线程 A 放心大胆地创建不就行了吗”答案为了防止“漏网之鱼”。模拟一个多线程并发的场景就明白了场景还原假设有两个线程线程 A 和 线程 B同时调用 getInstance()且此时 instance 为 null。第一步关键线程 A 执行到第 11 行 if (instance null)判断为 true需要创建。同时线程 B 也执行到第 11 行因为它还没被锁住它看到的 instance 也是 null判断也为 true。结果 A 和 B 都通过了第一层关卡来到了 synchronized 门外。第二步抢锁线程 A 动作快抢到了锁进入了 synchronized 块内部。线程 B 慢了一步被挡在门外进入阻塞等待状态。注意 此时线程 B 已经通过了第一个 if它只是在等锁而不是被第一个 if 挡回去。第三步A 创建对象线程 A 在锁内部执行 instance new SingletonLazy();。对象创建完毕instance 不再是 null。线程 A 释放锁离开。第四步B 的灾难锁被释放了线程 B 终于拿到了锁进入了 synchronized 块内部。如果没有第二次判断 线程 B 会直接执行 new SingletonLazy()。后果 虽然 A 已经创建了一个对象但 B 又创建了一个单例模式失效了变成了“双例”。第五步B 的救赎 - 第二次判断因为有了第 13 行的 if (instance null)。线程 B 进门后虽然它之前在门外看到的是 null但它进门后再看一眼发现 instance 已经被 A 初始化了不为 null。结果 线程 B 放弃创建直接退出。总结第一次判断 (if outside) 是为了性能。一旦对象创建好了后面的线程根本不需要排队抢锁直接拿走对象即可。第二次判断 (if inside) 是为了安全。防止在多线程并发的极端情况下两个线程同时通过了第一层检查导致重复创建对象。补充为什么instance 变量必须加上 volatile 关键字。在 Java 高并发环境下这段代码不加volatile关键字有一个隐患。// 必须加 volatileprivatestaticvolatileSingletonLazyinstance;原因 new SingletonLazy() 这个操作在计算机底层不是原子性的它分三步分配内存。初始化对象。将 instance 指向这块内存。如果没有 volatileCPU 可能会指令重排序比如变成 1 - 3 - 2。如果在执行完 1 和 3此时 instance 已经不为 null但对象还没初始化好时另一个线程来了它在第一次判断时发现 instance 不为 null直接拿去用了。结果就是拿到了一个半成品对象程序报错。volatile 的作用就是禁止指令重排序保证绝对安全。

相关文章:

java单例模式 懒汉式(双重检查锁)

/*** 懒汉式 方式6 双重检查锁*/ public class SingletonLazy {// 1、私有构造方法private SingletonLazy(){}// 2、在成员变量位置声明一个静态对象private static volatile SingletonLazy instance; // 关键字volatile:禁止指令重排序,确保绝对安全// …...

wUU代码混淆实战指南:使用Obfuscar构建坚不可摧的安全防线

在当今数字化时代,保护.NET应用程序的源代码安全变得尤为重要。你是否担心自己的知识产权被轻易窃取?是否希望防止竞争对手通过反编译分析你的核心业务逻辑?今天,我将为你详细介绍一款强大的开源混淆工具——Obfuscar,…...

Memfit AI 渗透测试智能体,到底能不能打?

深度测评:Memfit AI 渗透测试智能体,到底能不能打? 写在前面:这篇文章我写了整整一周,从安装部署到实际测试,把 Memfit AI 这个号称"下一代 AI 渗透测试平台"的工具从头到尾摸了一遍。先说结论&a…...

新手学吉他必看,这5个常见误区,避开了少走3个月弯路

经常会看到很多新手学吉他,学着学着就卡壳学不下去了,不是嫌按弦手疼,就是曲子弹不下去。特别是一些自学的朋友,网上随便东找些课,西看些视频,学下来进步很慢,3个月之后就改打“退堂鼓”了。其实…...

聊着天把虾队管了:用 HiClaw 正确打开多智能体协作方式【限时领 PPT】

作者:戴靖泽(静择) 本文整理自 DataWhale x HiClaw 直播分享,聊聊多 Agent 协作背后的工程思考。 点击此处,查看分享! 你有没有试过让一个 AI 同时写前端和后端?聊到后面它把自己定好的 API …...

OpenClaw低代码开发:Qwen2.5-VL-7B自动化流程设计器入门

OpenClaw低代码开发:Qwen2.5-VL-7B自动化流程设计器入门 1. 为什么需要可视化流程设计器? 上周我尝试用OpenClaw自动处理一批产品截图和说明文档时,遇到了一个典型问题:需要先让Qwen2.5-VL-7B识别图片中的关键元素,再…...

zotero使用记录

写在前面,我之前阅读文献使用endnote,仅仅使用他管理文献,然后使用豆包辅助阅读(翻译,搜索,总结,提问(看不懂的地方、公式推导都可以问)),最后使用vscode 编辑markdown 记笔记;这样一个流程看起…...

94吨黄金“上链搬家”,手续费仅0.0016%!黄金RWA正在改写跨境资产流动

传统金融数百万美元的物流成本vs区块链毫厘之间的链上费用,资产数字化的未来已来。近日,Tether首席执行官Paolo Ardoino在X平台发文称:过去6个月内,共有价值约94吨黄金的代币化黄金XAUT在链上完成转移,合计手续费仅约0…...

SwartNinjaPIR:嵌入式高可靠PIR运动检测驱动库

1. SwartNinjaPIR 库概述:面向嵌入式系统的高可靠性 PIR 运动检测驱动设计SwartNinjaPIR 是一个专为 Arduino 及兼容平台(如 STM32、ESP32 等基于 Arduino Core 的 MCU)设计的轻量级、生产就绪型被动红外(Passive Infrared, PIR&a…...

Vodafone K4606 USB调制解调器Linux内核驱动适配

1. Vodafone USB Modem 驱动适配技术解析:K4606 型号的底层支持实现 1.1 项目背景与工程定位 VodafoneUSBModem 是一个面向嵌入式 Linux 系统的 USB 串行通信驱动增强项目,其核心目标并非开发全新协议栈,而是对上游 Linux 内核中已有的 op…...

STM32电位器驱动库:轻量级ADC封装与中值滤波实现

1. 项目概述MentorBit-Potenciometro 是一款专为 MentorBit 系统设计的轻量级电位器(Potentiometer)模块驱动库,面向 STM32 平台(典型为 STM32F4/F7/H7 系列)的嵌入式固件开发。该库并非通用 ADC 抽象层,而…...

探索PLECS仿真下DAB变换器峰值电流前馈控制策略——IEEE顶刊复现之旅

PLECS仿真,IEEE顶刊复现,DAB变换器峰值电流前馈控制策略。最近在电力电子领域的研究中,我深入钻研了DAB(Dual - Active - Bridge)变换器的相关控制策略,并通过PLECS仿真实现了IEEE顶刊论文里一种峰值电流前…...

STM32智能展柜控制系统设计与实现

1. 项目概述在博物馆文物保存领域,环境参数的精确控制一直是个技术难点。我最近完成了一个基于STM32的智能展柜控制系统项目,这套方案能够实时监测并调节展柜内的温湿度及光照强度,为珍贵文物提供最佳保存环境。相比传统的人工监测方式&#…...

Python依赖包安装失败?一招搞定Microsoft Visual C++缺失问题

1. 为什么Python安装依赖包会提示缺少Microsoft Visual C? 这个问题困扰过无数Python开发者。当你兴致勃勃地敲下pip install xxx,结果却看到红色报错提示"Microsoft Visual C 14.0 or greater is required",那种感觉就像开车时突然…...

JAE日本航空电子推出满足汽车市场小型防水最新需求的MX80系列连接器

随着汽车电子化和高功能化的演进,每辆汽车所搭载的电子设备数量逐年增加。为了在有限安装空间内集成更多的功能,车载用电子零部件必然要求进一步小型化,高功能化。同时由于连接各设备之间的布线空间也在缩小,因此开发小型化&#…...

渗流完美降雨边界:单、双重渗透介质降雨边界处理的改进探索

渗流完美降雨边界——基于单、双重渗透介质降雨边界处理的改进 [1]模型简介:使用数值模拟软件COMSOL复现论文(窦智,刘一民,周志芳,等.基于单、双重渗透介质降雨边界处理的改进[J].岩土力学,2022,43(03):789-798.),该文献针对传统降…...

基于 PLC 的自动门控制系统设计与仿真程序探索

基于plc的自动门控制系统设计 仿真程序资料在自动化控制领域,基于 PLC(可编程逻辑控制器)的自动门控制系统应用广泛。今天咱就唠唠这基于 PLC 的自动门控制系统设计以及相关的仿真程序资料。 自动门控制系统设计需求 自动门要实现多种功能&a…...

数据转换器(ADC/DAC)核心术语与工程实践解析

1. 数据转换器基础概念解析在电子工程领域,数据转换器(ADC/DAC)是连接模拟世界与数字系统的关键桥梁。作为一名从业十余年的硬件工程师,我经常遇到新手对这些专业术语感到困惑的情况。本文将系统梳理56个核心术语,结合…...

全球不到3%的C++开发者掌握的量子模拟技巧:利用constexpr量子门编译期展开,启动速度提升41倍

第一章:量子计算 C 量子比特模拟示例在经典C环境中模拟量子比特行为,是理解量子门操作与叠加态演化的有效教学手段。本节基于线性代数原理,使用标准C17及以上特性(无需外部量子SDK),通过复数向量与酉矩阵实…...

Windows苹果设备驱动终极指南:3分钟搞定iPhone/iPad连接难题

Windows苹果设备驱动终极指南:3分钟搞定iPhone/iPad连接难题 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/…...

深入解析RPN(区域生成网络):从原理到Faster RCNN的实战应用

1. RPN的前世今生:从Selective Search到神经网络革命 第一次接触物体检测时,我对着Selective Search算法输出的杂乱无章的建议框直挠头。这个传统方法就像在图片上撒豆子,不仅速度慢(CPU处理单张图要2秒),…...

seo网站制作如何选择合适的关键词

SEO网站制作如何选择合适的关键词 在当今互联网时代,一个成功的网站不仅需要精美的设计,还需要强大的搜索引擎优化(SEO)技术。其中,关键词选择是SEO策略中至关重要的一环。选择合适的关键词不仅能够提高网站在百度等搜…...

OpenClaw + Seedance 2.0实战:从零搭建全自动AI视频生成流水线

OpenClaw Seedance 2.0实战:从零搭建全自动AI视频生成流水线 前言 这篇记录我用OpenClaw Agent串联Seedance 2.0满血版API,搭建全自动视频生产流水线的完整过程。包括架构设计、Skill编写、API调用细节和踩坑记录。 一、架构设计 用户输入&#xff…...

DOCX转LaTeX:从繁琐排版到学术自动化的无缝过渡

DOCX转LaTeX:从繁琐排版到学术自动化的无缝过渡 【免费下载链接】docx2tex Converts Microsoft Word docx to LaTeX 项目地址: https://gitcode.com/gh_mirrors/do/docx2tex 痛点场景:学术写作中的格式转换困境 深夜三点,研究生小李盯…...

从一次RDP爆破到全网挖矿:复盘Windows Server 3389端口的安全加固与监控策略

Windows Server 3389端口安全防御体系:从RDP爆破到挖矿攻击的全链路防护 最近处理了一起典型的服务器入侵事件:攻击者通过RDP暴力破解获取管理员权限后,在服务器上部署了挖矿程序。这种攻击模式看似简单,却暴露出许多企业在Windo…...

突破音频限制:OpenCore-Legacy-Patcher焕新老Mac音质体验

突破音频限制:OpenCore-Legacy-Patcher焕新老Mac音质体验 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当经典Mac设备升级到最新macOS系统后&am…...

【OpenClaw 安全部署与使用指南:从零构建可信赖的 AI 助手】

OpenClaw 安全部署与使用指南:从零构建可信赖的 AI 助手OpenClaw 作为一款具备"眼和手"的开源 AI Agent 框架,能够读写文件、执行命令、调用工具、访问网络——这些强大的能力在带来便利的同时,也意味着潜在的安全风险。如果部署和…...

Docker环境下SEEDLab BGP实验全流程避坑指南(附DNS/HTTP超时解决方案)

Docker环境下SEEDLab BGP实验深度实战手册 在网络安全教学领域,SEEDLab系列实验因其高度仿真的网络环境和精心设计的攻防场景,成为培养实战能力的重要工具。当这些实验与Docker容器技术结合时,既能复现复杂网络拓扑,又带来了环境配…...

TGP Ecran:Arduino OLED显示库的轻量封装与非阻塞刷新设计

1. 项目概述TGP Ecran 是一款面向嵌入式 Arduino 平台的 OLED 显示驱动封装库,其核心定位是降低 Adafruit SSD1306 驱动库的使用门槛,同时保留底层图形能力的完整可访问性。该库并非从零实现的显示驱动,而是基于 Adafruit 官方 SSD1306 和 GF…...

嵌入式开发中的模块化编程与驱动分离实践

1. 模块化编程与驱动分离的核心价值在嵌入式开发领域,模块化编程早已不是新鲜概念。我第一次真正体会到它的威力是在2016年参与某新能源汽车BMS(电池管理系统)开发时。当时团队里有8个工程师同时开发不同功能模块,如果没有严格的模…...