iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java双重校验锁单例原理
  • 656
分享到

Java双重校验锁单例原理

2024-04-02 19:04:59 656人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言正文代码实现总结前言 作为开发者,单例这个就再也熟悉不过了,但是作为多种单例实现模式,我个人觉得双重校验锁是非常不多的实现,我们简单来分析一下其原理。 正文 先来说一下Jav

前言

作为开发者,单例这个就再也熟悉不过了,但是作为多种单例实现模式,我个人觉得双重校验是非常不多的实现,我们简单来分析一下其原理。

正文

先来说一下Java版本的,后面会涉及Kotlin中的代码我们再做比对。

代码实现

Java代码实现如下:

//双重校验锁单例
public class SingleInstance {
    //必须volatile修饰 见分析1
    private volatile static SingleInstance instance;
    //私有化构造函数
    private SingleInstance() {
    }
 
    public static SingleInstance getInstance() {
        //第一个判空 见分析2
        if (instance == null) {
            synchronized (SingleInstance.class) {
                //第二个判空 见分析3
                if (instance == null) {
                    //新建实例
                    instance = new SingleInstance();
                }
            }
        }
        return instance;
    }
}

首先这里synchronized关键字没有修饰整个getInstance函数,因为这个函数可能使用地方很多,这样就会造成其他线程阻塞,不太好,所以这里只同步了一段代码。

分析2:为什么在进入同步代码块时需要进行进行判空,假如有线程A和线程B,这时线程A先判断instance为null,所以它进入了同步代码块,创建了对象,然后线程B再进来时,它就不必再进入同步代码快了,可以直接返回,也其实也就是懒加载,可以加快执行速度。

分析3:为什么在同步代码块中还要再进行一次判断呢,假如有线程A和线程B,它俩A先调用方法,B紧接着调用,这时A、B在分析2出的判空都是空,所以A进入同步代码块,B进行等待,当A进入同步代码块中创建了对象后,A线程释放了锁,这时B再进入,如果这时不加分析3的判空,B又会创建一个实例,这明显不符合规矩。

分析1:那既然加了2层判断,那为什么还要加个volatile关键字呢,这里知识点就有点多了。

因为新建实例的代码:

instance = new SingleInstance();

它不是一个原子操作,这个简单的赋值可以分为3步:

1、给SingleInstance分配内存

2、调用SingleInstance的构造方法

3、把instance指向分配的内存空间

这是正常逻辑的3个步骤,也只有按1 2 3执行后,这个instance才不是null。

但是Java内存模型允许这个进行指令重排序,也就是这3步可能是123也可能是132,所以这里就有问题了。

假如线程A和线程B,线程A已经跑到分析3处的代码,这时这条指令执行是132,刚把步骤3执行完,这时线程B跑到了分析1处的代码,会发现instance不为null了,这时线程B就直接返回了,从而导致错误。

既然知道了原因,那volatile关键字就是解决这个的,它可以禁止指令重新排序,而且保证所有线程看到这个变量是一致的,也就是不会从缓存中读取(这个特性后面有机会再说),所以在创建instance实例时,它的步骤都是123,就不会出错了。

总结

到此这篇关于Java双重校验锁单例原理的文章就介绍到这了,更多相关Java校验锁单例内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java双重校验锁单例原理

本文链接: https://www.lsjlt.com/news/163239.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java双重校验锁单例原理
    目录前言正文代码实现总结前言 作为开发者,单例这个就再也熟悉不过了,但是作为多种单例实现模式,我个人觉得双重校验锁是非常不多的实现,我们简单来分析一下其原理。 正文 先来说一下Jav...
    99+
    2024-04-02
  • Java怎么实现双重校验锁单例
    这篇文章主要介绍了Java怎么实现双重校验锁单例的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么实现双重校验锁单例文章都会有所收获,下面我们一起来看看吧。代码实现Java代码实现如下://双重校验锁单...
    99+
    2023-06-28
  • 双重检查锁定模式Java中的陷阱案例
    目录1、简介2、Java中的双重检查锁定3、列举方案3.1 利用 ThreadLocal3.2 利用volatile(解决重排序问题)4、总结1、简介 双重检查锁定(也叫做双重检查锁...
    99+
    2024-04-02
  • Java ynchronized重量级锁的核心原理详解
    目录1.monitor原理2.snychronized同步代码块原理3.synchronized同步方法原理4.重量级锁的开销总结在JVM中,每个对象都关联一个监视器,这里的对象包含...
    99+
    2024-04-02
  • Java中锁的实现原理和实例用法
    这篇文章主要介绍“Java中锁的实现原理和实例用法”,在日常操作中,相信很多人在Java中锁的实现原理和实例用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中锁的实现原理和实例用法”的疑惑有所帮助!...
    99+
    2023-06-16
  • Java单例模式与破坏单例模式概念原理深入讲解
    目录什么是单例模式饿汉式(预加载)懒汉式(懒加载)反射破坏单例模式什么是单例模式 经典设计模式又分23种,也就是GoF 23 总体分为三大类: 创建型模式结构性模式行为型模式 Jav...
    99+
    2023-02-21
    Java单例模式 Java破坏单例模式
  • 详解Java ReentrantLock可重入,可打断,锁超时的实现原理
    目录概述可重入可打断锁超时概述 前面讲解了ReentrantLock加锁和解锁的原理实现,但是没有阐述它的可重入、可打断以及超时获取锁失败的原理,本文就重点讲解这三种情况。建议大家先...
    99+
    2022-11-13
    Java ReentrantLock可重入 Java ReentrantLock可打断 Java ReentrantLock锁超时 Java ReentrantLock
  • java单元测试JUnit框架原理的示例分析
    小编给大家分享一下java单元测试JUnit框架原理的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:1 简介JUnit是一个Java语言的单元测试框架,它由 Kent Beck 和 Erich Gamma...
    99+
    2023-05-30
    java junit
  • 详解Java单例模式的实现与原理剖析
    目录一、什么是单例模式二、哪些地方用到了单例模式三、单例模式的优缺点优点缺点四、手写单例模式饿汉式枚举饿汉式DCL懒汉式双检锁懒汉式内部类懒汉式小结一、什么是单例模式 单例模式(Si...
    99+
    2024-04-02
  • Java LongAdder类介绍、代码示例、底层实现原理及与分段锁的区别
    LongAdder介绍 LongAdder是Java并发包(java.util.concurrent)中的一个类,用于高效地实现多线程环境下的加法操作。 在多线程环境中,如果多个线程同时对同一个变量进...
    99+
    2023-09-06
    java jvm 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作