广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Javasynchronized底层的实现原理
  • 756
分享到

Javasynchronized底层的实现原理

2024-04-02 19:04:59 756人浏览 八月长安

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

摘要

目录监视器底层实现执行流程总结前言: 想了解 synchronized 是如何运行的?就要先搞清楚 synchronized 是如何实现? synchronized 同步锁是通过 J

前言:

想了解 synchronized 是如何运行的?就要先搞清楚 synchronized 是如何实现? synchronized 同步是通过 JVM 内置的 Monitor 监视器实现的,而监视器又是依赖操作系统的互斥锁 Mutex 实现的,那接下来我们先来了解一下监视器。

监视器

监视器是一个概念或者说是一个机制,它用来保障在任何时候,只有一个线程能够执行指定区域的代码。

一个监视器像是一个建筑,建筑里有一个特殊的房间,这个房间同一时刻只能被一个线程所占有。一个线程从进入该房间到离开该房间,可以全程独占该房间的所有数据。进入该建筑叫做进入监视器(entering the monitor),进入该房间叫做获得监视器(acquiring the monitor),独自占有该房间叫做拥有监视器(owning the monitor),离开该房间叫做释放监视器(releasing the monitor),离开该建筑叫做退出监视器(exiting the monitor)。

严格意义来说监视器和锁的概念是不同的,但很多地方也把二者相互指代。

底层实现

下面我们在代码中添加一个 synchronized 代码块,来观察一下它在字节码层面是如何实现的?

示例代码如下:

public class SynchronizedToMonitorExample {
    public static void main(String[] args) {
        int count = 0;
        synchronized (SynchronizedToMonitorExample.class) {
            for (int i = 0; i < 10; i++) {
                count++;
            }
        }
        System.out.println(count);
    }
}

当我们将上述代码编译成字节码之后,得到的结果是这样的: 

 从上述结果我们可以看出,在 main 方法中多了一对 monitorenter 和 monitorexit 的指令,它们的含义是:

  • monitorenter:表示进入监视器。
  • monitorexit:表示退出监视器。

由此可知 synchronized 是依赖 Monitor 监视器实现的。

执行流程

在 Java 中,synchronized 是非公平锁,也是可以重入锁。 所谓的非公平锁是指,线程获取锁的顺序不是按照访问的顺序先来先到的,而是由线程自己竞争,随机获取到锁。 可重入锁指的是,一个线程获取到锁之后,可以重复得到该锁。这些内容是理解接下来内容的前置知识。 在 HotSpot 虚拟机中,Monitor 底层是由 c++实现的,它的实现对象是 ObjectMonitor,ObjectMonitor 结构体的实现如下:

ObjectMonitor::ObjectMonitor() {
  _header       = NULL;
  _count       = 0;
  _waiters      = 0,
  _recursions   = 0;       //线程的重入次数
  _object       = NULL;
  _owner        = NULL;    //标识拥有该monitor的线程
  _WaitSet      = NULL;    //等待线程组成的双向循环链表,_WaitSet是第一个节点
  _WaitSetLock  = 0 ;
  _Responsible  = NULL ;
  _succ         = NULL ;
  _cxq          = NULL ;    //多线程竞争锁进入时的单向链表
  FreeNext      = NULL ;
  _EntryList    = NULL ;    //_owner从该双向循环链表中唤醒线程结点,_EntryList是第一个节点
  _SpinFreq     = 0 ;
  _SpinClock    = 0 ;
  OwnerIsThread = 0 ;
} 

在以上代码中有几个关键的属性:

  • _count:记录该线程获取锁的次数(也就是前前后后,这个线程一共获取此锁多少次)。
  • _recursions:锁的重入次数。
  • _owner:The Owner 拥有者,是持有该 ObjectMonitor(监视器)对象的线程;
  • _EntryList:EntryList 监控集合,存放的是处于阻塞状态的线程队列,在多线程下,竞争失败的线程会进入 EntryList 队列。
  • _WaitSet:WaitSet 待授权集合,存放的是处于 wait 状态的线程队列,当线程执行了 wait() 方法之后,会进入 WaitSet 队列。

监视器执行的流程如下:

  • 线程通过 CAS(对比并替换)尝试获取锁,如果获取成功,就将 _owner 字段设置为当前线程,说明当前线程已经持有锁,并将 _recursions 重入次数的属性 +1。如果获取失败则先通过自旋 CAS 尝试获取锁,如果还是失败则将当前线程放入到 EntryList 监控队列(阻塞)。
  • 当拥有锁的线程执行了 wait 方法之后,线程释放锁,将 owner 变量恢复为 null 状态,同时将该线程放入 WaitSet 待授权队列中等待被唤醒。
  • 当调用 notify 方法时,随机唤醒 WaitSet 队列中的某一个线程,当调用 notifyAll 时唤醒所有的 WaitSet 中的线程尝试获取锁。
  • 线程执行完释放了锁之后,会唤醒 EntryList 中的所有线程尝试获取锁。

以上就是监视器的执行流程,执行流程如下图所示:

总结

synchronized 同步锁是通过 JVM 内置的 Monitor 监视器实现的,而监视器又是依赖操作系统的互斥锁 Mutex 实现的。JVM 监视器的执行流程是:线程先通过自旋 CAS 的方式尝试获取锁,如果获取失败就进入 EntrySet 集合,如果获取成功就拥有该锁。当调用 wait() 方法时,线程释放锁并进入 WaitSet 集合,等其他线程调用 notify 或 notifyAll 方法时再尝试获取锁。锁使用完之后就会通知 EntrySet 集合中的线程,让它们尝试获取锁。

到此这篇关于Java synchronized底层的实现原理的文章就介绍到这了,更多相关Java synchronized内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Javasynchronized底层的实现原理

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

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

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

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

下载Word文档
猜你喜欢
  • Javasynchronized底层的实现原理
    目录监视器底层实现执行流程总结前言: 想了解 synchronized 是如何运行的?就要先搞清楚 synchronized 是如何实现? synchronized 同步锁是通过 J...
    99+
    2022-11-13
  • HashMap的底层实现原理
    这篇文章主要介绍“HashMap的底层实现原理”,在日常操作中,相信很多人在HashMap的底层实现原理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”HashMap的底层实现原理”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-04
  • hashmap底层实现原理
    一、hashmap底层实现原理 HashMap是基于哈希表的Map接口的非同步实现。元素以键值对的形式存放,并且允许null键和null值,因为key值唯一(不能重复),因此,null键只有一个。另外,hashmap不保证元素存储的顺...
    99+
    2023-10-29
    底层 原理 hashmap
  • synchronized底层实现原理
    测试类: public class SynchronizedTest {     public void get() {         synchronized (this) { ...
    99+
    2022-11-13
  • 浅谈React底层实现原理
    目录1. props,state与render函数关系,数据和页面如何实现互相联动?2. React中的虚拟DOM常规思路改良思路(仍使用DOM)React的思路深入理解虚拟DOM3...
    99+
    2022-11-13
  • chatgpt底层实现的原理是什么
    chatgpt底层实现的原理是通过人工的标注方式来训练出一种强化学习的冷启动模型和reward反馈模型,然后再通过强化学习的模式来学...
    99+
    2023-02-09
    chatgpt
  • Synchronized的底层实现原理是什么
    Synchronized的底层实现原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。(1)给静态方法加锁public&n...
    99+
    2022-10-19
  • HashMap的底层实现原理是什么
    这篇文章给大家介绍HashMap的底层实现原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.HashMap的常用方法//  Hashmap存值:----------------------...
    99+
    2023-06-06
  • Java LinkedHashMap 底层实现原理分析
    目录添加元素 删除元素 更新元素查找元素 其他方法 迭代器总结 在实现上,LinkedHashMap很多方法直接继承自HashMap,仅为维护双向链表覆写了部分方法。所以,要看懂 L...
    99+
    2022-11-12
  • Go WaitGroup及Cond底层实现原理
    目录WaitGroup概念底层数据结构使用方法Cond概念底层数据结构使用方法WaitGroup 概念 Go标准库提供了WaitGroup原语, 可以用它来等待一批 Goroutin...
    99+
    2022-11-11
  • Go语言底层原理互斥锁的实现原理
    目录Go 互斥锁的实现原理?概念使用场景底层实现结构操作加锁解锁Go 互斥锁正常模式和饥饿模式的区别?正常模式(非公平锁)饥饿模式(公平锁)Go 互斥锁允许自旋的条件?Go 互斥锁的...
    99+
    2022-11-11
  • Java中SynchronousQueue的底层实现原理剖析
    目录1. SynchronousQueue用法2. SynchronousQueue应用场景3. SynchronousQueue源码解析3.1 SynchronousQueue类属...
    99+
    2022-11-21
    Java SynchronousQueue实现 Java SynchronousQueue原理 Java SynchronousQueue
  • 关于Python字典的底层实现原理
    目录字典是否是有序字典的查询、添加、删除的时间复杂度字典的实现原理Python3.6之前的无序字典带入具体的数值来介绍Python3.7+后的新的实现方式Python3.7+带入数据...
    99+
    2023-02-10
    Python字典 字典底层实现原理 Python字典实现原理
  • 【C++】多态的实现及其底层原理
    个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处。 文章目录 前言一、什么是多态?二、多态的构成条件2.1什么是虚函数?2.2虚函数的重...
    99+
    2023-08-17
    c++ 开发语言 多态
  • 深入详解Vue3ref底层实现原理
    目录前言源码解析实践操作class类的get和set是什么结论前言 随着现在vue3越来越普及,相应的面试题也多了起来 说到vue3的面试题,有一个最经典的就是ref和reactiv...
    99+
    2023-05-17
    Vue3 ref实现原理 Vue3 ref原理 Vue3 ref
  • spring aop底层原理及如何实现
    目录前言 使用 源码分析 总结 前言 相信每天工作都要用spring框架的大家一定使用过spring aop,aop的概念是面向切面编程,相对与传统的面向对象编程oop,aop更关...
    99+
    2022-11-12
  • Golang函数底层实现原理探讨
    Golang函数底层实现原理探讨Golang语言中的函数是非常重要的一个特性,但是很少有人关注其底层实现原理。本文将深入探讨Golang函数的底层实现原理,希望读者能够更好地理解和优化自己的代码。Golang函数的定义在Golang中,函数...
    99+
    2023-05-17
    函数 Golang 底层实现
  • spring aop底层原理及实现方法
    这篇文章主要介绍spring aop底层原理及实现方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!使用要分析spring aop的底层原理,首先要会使用,先创建一个普通maven webapp项目,引入spring...
    99+
    2023-06-14
  • golang map底层实现原理是什么
    Golang中的map是基于散列表(hash table)实现的。散列表是一种用于存储键值对的数据结构,它通过将键映射到数组的索引来...
    99+
    2023-10-21
    golang
  • Synchronized的底层实现原理(原理解析,面试必备)
    synchronized 一. synchronized解读 1.1 简单描述 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为同步锁。 synchronize...
    99+
    2023-08-19
    面试 java jvm
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作