首页 > 其他分享 >为什么双重检验锁需要两次判空?

为什么双重检验锁需要两次判空?

时间:2024-08-12 22:06:35浏览次数:14  
标签:加锁 DCLTest 双重 检验 instance 线程 修饰 判空

背景

本文将讲解单例模式-双重检验锁的实现。

代码实现

public class DCLTest {
    private  volatile static DCL instance;
    private  DCLTest () {};
    public static  DCLTest getInstance() { // 不用synchronized修饰方法,效率高
        if (instance == null) {
            synchronized (DCLTest .class) {
                if (instance == null) { 
                    instance = new DCLTest ();
                }
            }
        }
        return instance;
    }
}

实现思路

这边主要解释以下几个问题。

1.为什么要进行两次判空?

答:首先,存在即合理。观察代码,synchronzied内部这个判空是必须要进行的,因为我们是单例嘛,ioc容器中只存在一个单例对象就好了。多线程的时候,如果这个对象已经被创建,那其他线程就不用继续去new一个实例对象,如果不存在,才去new这个单例对象。
对于synchronzied以外的这个判空,其实是做了一个优化。因为在多线程环境下,如果不加这个判空的话,每个线程访问这个方法的时候,都会直接访问到synchronized块,从而对类对象进行加锁。我们知道,加锁这个操作对性能消耗还是挺大的,因为会引起线程的上下文切换,内核态和用户态的转换。尤其是并发环境下,这个性能消耗会更加明显。
所以,外层的判空是针对性能做出的优化,避免每个线程都去加锁。只有实例对象为空的时候,当前线程才会去加锁。

2.为什么使用volatile修饰instance实例对象?

答: 这边使用volatile修饰,主要是为了禁止指令重排序,从而避免由于指令重排序而带来的一个问题(可能会访问一个还未进行初始化的对象)。
因为如果访问一个还未初始化的对象,会报空指针异常。

3.为什么使用synchronzied来修饰代码块?synchronzied为什么没有直接修饰这个getInstance()方法?

答:synchronized块用来保证在多线程环境下只有一个线程可以执行实例化操作。
不直接修饰方法其实也是为了提高程序的效率。因为如果直接修饰方法的话,对于每个访问的线程,都要先去获取锁资源,再执行相应的逻辑。
直接修饰代码块,就可以避免每个线程都竞争锁资源了。

标签:加锁,DCLTest,双重,检验,instance,线程,修饰,判空
From: https://www.cnblogs.com/xyuanzi/p/18355816

相关文章

  • 单例模式-饿汉、懒汉(线程安全、双重检查锁定)、静态内部类、枚举
    1饿汉式这种方式是最简单的单例模式实现,它在类加载的时候就创建了单例对象。优点实现简单线程安全缺点无论是否使用,都会加载单例类并创建单例对象publicclassSingleton{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){......
  • Kolmogorov-Smirnov 检验 + k 样本 Anderson-Darling 检验 + 贝叶斯估计 + 期望/方差
    KS检验是基于Kolmogorovdistribution,指的是\[K=\sup_{t\in[0,1]}\left\lvertB(t)\right\rvert\]式中\(B(t)\)是布朗桥。\(K\)的累积分布函数是\[\Pr(K\lex)=1-2\sum_{k=1}^\infty(-1)^{k-1}\mathrme^{-2k^2x^2}=\frac{\sqrt{2\pi}}x\sum_{k=1}^\infty\mathrme^......
  • 相关性检验
    文章目录Pearson相关系数Spearman等级相关系数Cochran'sQ检验Kappa一致性系数Kendall相关系数实例分析总结在数据分析的广阔天地中,相关性检验是探索变量间关系的一把钥匙。本文将带领大家了解几种常用的相关性检验方法:Pearson、Spearman、Cochran’sQ、Kappa和Kenda......
  • STM32H7 HAL库CubeMX 双重ADC模式同步采样详细配置+FFT计算相位差
    前言在电赛备赛期间琢磨了一下ADC同步采样的实现方式,本来是打算直接用AD7606来着,但是搞了半天也没把驱动整出来...考虑到AD7606本身采样率也拉不到太高,于是就花了几天时间把片上ADC配出来了。查资料的时候我发现关于STM32双重ADC模式的资料是真的少,用FFT算两路信号相位差的实例代......
  • 天气雷达双重频解速度模糊
    雷达能探测到的目标的最大径向速度与脉冲重复周期有关,当探测目标的速度超过最大不模糊速度,就会出现速度模糊的现象,利用双脉冲重复频率可以在保持最大不模糊距离不变的情况下扩大探测的最大不模糊速度。具体原理如下:假设以一种脉冲重复频率PRF1收集M个脉冲样本,另一种脉冲重复......
  • Python数据预处理+正态性检验+异常值处理+Q-Q图-K-S检验+相关性分析(2024MathorCup A题
    #数据预处理#正态性检验、Q-Q图、箱线图、直方图、相关性分析#Q-Q图importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltfromscipy.statsimportnormfromscipy.statsimportprobplota=pd.read_excel('附件1:小区基本信息.xlsx',engine='openpyxl'......
  • 探索 GPT-4o mini:成本效益与创新的双重驱动
    ......
  • 龙哥量化:楔形形态突破后的预判空间(图解)
    如果您需要代写技术指标公式,请联系我。龙哥QQ:591438821龙哥微信:Long622889不同于三角形、箱体平台和顶底形态那么“常见”和“容易辨认”,楔形显得较陌生。但同样可以通过形态突破来做个股的涨跌预判。首先,区别于旗形上下边的平行关系,楔形上下两条边是同向但逐渐往内收敛。......
  • 效率与创意的双重飞跃?AI生成工具:你的秘密武器
    作为一名AI爱好者,我积累了许多实用的AI生成工具。今天,我想分享一些我经常使用的工具,这些工具不仅能帮助提升工作效率,还能激发创意思维。我们都知道,随着技术的进步,AI生成工具已经变得越来越智能,能够在多个领域提供强大的支持。它们涵盖了文案写作、图像处理、PPT制作等多个领域......
  • 医学实验室检验系统源码 C#语言LIS系统全套源码,多家大型综合医院应用案例,适合二次开发
    实验室管理信息系统LIS源码,采用.NetC#语言开发,C/S架构。支持DB2,Oracle,MSSQLServer等主流数据库。(全套LIS系统源码,自主版权,多家大型综合医院应用案例,适合二次开发,项目应用)LIS系统菜单功能:1、系统维护基础数据维护、项目相关维护、人员权限维护、打印模板维护、微生物维......