synchronized 底层是如何实现的 ?

news2025/1/21 12:00:06

目录

1. synchronized 底层是如何实现的

2. 监视器的执行流程


1. synchronized 底层是如何实现的

synchronized 底层是通过 JVM 内置的 Monitor 监视器实现的。

以下代码,查看它运行时的字节码文件:

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

使用 IDEA 字节码插件 Bytecode Viewer 查看字节码文件: 

从字节中可以看到两个指令:

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

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

2. 监视器的执行流程

        既然我们知道了 synchronized 的底层是依赖 Monitor 监视器来实现的,那么监视器它到底是怎么执行的呢 ?知其然还要知其所以然~

什么是监视器?

监视器它是一种机制,用来保障在任何时候,只有一个线程能够执行某个区域内的代码。

一个监视器可以看作是一栋房子,房子里有一个特殊的房间,这个房间同一时刻只能被一个线程所占有。占有该房间的线程可以共享该房间的所有数据。

进入该房子:进入监视器

进入该房间:获得监视器

离开该房间:释放监视器

离开该房子:退出监视器

在 hosSpot 虚拟机中,监视器底层是由 C++ 实现的,它的实现是一个结构体对象,它里面有以下几个重要属性:

  • _count:记录该线程获取锁的次数;
  • _recursions:记录锁的重入次数;
  • _owner:表示拥有监视器对象的线程;
  • _EntryList:表示监控集合,用于存放多线程情况下,竞争监视器失败的线程(处于阻塞状态的线程队列);
  • _WaitSet:表示待授权集合,用于存放进入 waiting 状态的线程队列(当线程调用了 wait() 方法就会进入该集合)。

具体执行流程参考下图>>

监视器

它的执行流程大致是这样的 >>

  1. 线程通过 CAS(compare and swap) 尝试获取锁,如果获取成功了,就将 _owner 字段设置给当前线程,表示当前线程持有监视器锁,并将 _recusions 重入次数 + 1;如果获取失败,则通过 CAS 自旋不断尝试获取锁,尝试一定次数还是失败,那么就加入到 EntrySet 监控集合中(阻塞)。
  2. 当持有监视器锁的线程调用了 wait() 方法,当前线程就会释放锁,并将 _owner 字段恢复为 null,同时将当前线程加入到 WaitSet 待授权集合中,等待被唤醒。
  3. 当调用 notify() 方法时,随机唤醒 WaitSet 待授权集合中的某一个线程,当调用 notifyAll() 方法时,唤醒 WaitSet 待授权集合中所有的线程尝试获取锁。
  4. 线程执行完释放锁后,唤醒 EntrySet 监控集合中的所有的线程尝试获取锁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/883755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 主从复制遇到 1590 报错

作者通过一个主从复制过程中 1590 的错误&#xff0c;说明了 MySQL 8.0 在创建用户授权过程中的注意事项。 作者&#xff1a;王祥 爱可生 DBA 团队成员&#xff0c;主要负责 MySQL 故障处理和性能优化。对技术执着&#xff0c;为客户负责。 本文来源&#xff1a;原创投稿 爱可生…

【图像分类】理论篇(4)图像增强opencv实现

随机旋转 随机旋转是一种图像增强技术&#xff0c;它通过将图像以随机角度进行旋转来增加数据的多样性&#xff0c;从而帮助改善模型的鲁棒性和泛化能力。这在训练深度学习模型时尤其有用&#xff0c;可以使模型更好地适应各种角度的输入。 原图像&#xff1a; 旋转后的图像&…

当Visual Studio遇到 “当前不会命中断点.还没有为该文档加载任何符号“的情况

1.配置项目调试路径&#xff1a; 2.问题解决方案&#xff1a; VS配置调试路径不是默认路径时&#xff0c;需要看生成的文件是否在配置路径内&#xff0c;如果不在的话&#xff0c;可能发生"当前不会命中断点.还没有为该文档加载任何符号"的情况&#xff1b; 右键项…

【贪心】CF1779 D

不会1700 Problem - 1779D - Codeforces 题意&#xff1a; 思路&#xff1a; 首先手推样例&#xff0c;可以发现一些零碎的性质&#xff1a; 然后考虑如何去计算贡献 难点在于&#xff0c;当一个区间的两端是区间max时&#xff0c;怎么去计算贡献 事实上&#xff0c;只需要…

input输入框自动填充后消除背景色

一般自动填充后会有一个突出的浅蓝色背景&#xff0c;一定也不好看&#xff0c;所以想把它去掉&#xff1a; 这个时候&#xff0c;就要用到浏览器的样式设置了&#xff1a; input:-webkit-autofill {background: transparent;transition: background-color 50000s ease-in-ou…

浅谈5G技术会给视频监控行业带来的一些变革情况

5G是第五代移动通信技术&#xff0c;能够提供更高的带宽和更快的传输速度&#xff0c;这将为视频技术的发展带来大量机会。随着5G技术的逐步普及与商用&#xff0c;人们将能够享受到更加流畅的高清视频体验&#xff0c;并且5G技术还拥有更低的延迟和更高的网络容量。这些优势不…

Android Shape 的使用

目录 什么是Shape? shape属性 子标签属性 corners &#xff08;圆角&#xff09; solid &#xff08;填充色&#xff09; gradient &#xff08;渐变&#xff09; stroke &#xff08;描边&#xff09; padding &#xff08;内边距&#xff09; size &#xff08;大小…

校园外卖小程序怎么做

校园外卖小程序是为满足校园内学生和教职员工的外卖需求而开发的一种应用程序。它涵盖了从用户端、商家端、骑手端、电脑管理员到小票打印、多商户入驻等多个方面的功能&#xff0c;以下将逐一介绍。 1. 用户端功能&#xff1a;校园外卖小程序为用户提供了便捷的订餐和外卖服务…

谦卦-六爻皆吉

前言&#xff1a;满招损&#xff0c;谦受益&#xff0c;谦卦在六十四卦是唯一的六爻皆吉的卦&#xff0c;今天学习谦卦的卦辞和爻辞。 卦辞 亨&#xff0c;君子有终。 序卦&#xff1a;有大者不可以盈&#xff0c;故受之以谦 篆曰&#xff1a;谦&#xff0c;亨&#xff0c;天…

解读注解@Value占位符替换过程

之前写过一篇关于介绍Spring占位符替换原理的博客&#xff0c;传送门 &#xff1a;Spring的占位符是怎么工作的 在这篇文章基础上&#xff0c;再介绍一下Value替换原理&#xff0c;两篇文章有一定的相关性。 继续以上一篇的工程为例&#xff0c;项目结构一样&#xff0c;这里就…

微波雷达感应模块XBG-M556

一、概括 XBG-M556是一款采用多普勒雷达技术,专门检测物体移动的微波感应模块。采用2.9G微波信号检测&#xff0c;该模块具有灵敏度高&#xff0c;可靠性强&#xff0c;感应角度大&#xff0c;工作电压宽等特点。高电平输出&#xff0c;可直接驱动外部 LED灯或负载。输入电压高…

Linux中执行一个Sheel脚本/系统重启后自动执行脚本

Linux中执行一个Sheel脚本 一&#xff1a;编写一个重启Java服务的.sh脚本 Windows中创建一个restart.sh文件 将一下脚本内容copy中restart.sh文件中 #!/bin/bashJAR_NAME"cloud.jar" LOG_FILE"restart.log"# 进入目录 cd /opt/server/cloudRecord/# 检查…

探索API接口的奥秘:解析与应用

什么是API接口&#xff1f;为什么它如此重要&#xff1f; 在现代技术和互联网时代&#xff0c;API接口是互联网服务之间实现数据传输和交流的关键链接。 API&#xff08;应用程序编程接口&#xff09;是一组定义了不同软件组件之间交互的规则和约定。 它允许不同的软件系统之间…

通过Git使用GitHub

目录 一、建立个人仓库 二、配置SSH密钥 三、克隆仓库代码 四、推送代码到个人仓库 五、代码拉取 一、建立个人仓库 1.建立GitHub个人仓库&#xff0c;首先注册GitHub用户。注册好了之后&#xff0c;打开用户的界面 然后就是配置问题 配置好后拉到最下方点击create repos…

day9 STM32 I2C总线通信

I2C总线简介 I2C总线介绍 I2C&#xff08;Inter-Integrated Circuit&#xff09;总线&#xff08;也称IIC或I2C&#xff09;是由PHILIPS公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备&#xff0c;是微电子通信控制领域广泛采用的一种总线标准。 它是同步通…

MFA多因素认证和TOTP认证逻辑解析

MFA多因素认证与TOTP认证逻辑解析 在今天的数字时代&#xff0c;隐私和安全变得尤为重要。用户越来越需要确保他们的在线账户和敏感信息不会落入不法分子之手。为此&#xff0c;多因素认证&#xff08;Multi-Factor Authentication&#xff0c;MFA&#xff09;应运而生&#x…

Linux系统编程:采用管道的方式实现进程间通信

目录 一. 进程间通信概述 二. 管道的概念 三. 通过管道实现进程间通信 3.1 实现原理 3.2 匿名管道创建系统接口pipe 3.3 管道通信的模拟实现 3.4 管道通信的访问控制规则 3.5 管道通信的特点 四. 通过匿名管道实现进程池 4.1 进程池的概念 4.2 进程池的模拟实现 五…

Android 广播发送流程分析

在上一篇文章中Android 广播阻塞、延迟问题分析方法讲了广播阻塞的分析方法&#xff0c;但是分析完这个问题&#xff0c;自己还是有一些疑问&#xff1a; 广播为啥会阻塞呢&#xff1f;发送给接收器就行了&#xff0c;为啥还要等着接收器处理完才处理下一个&#xff1f;由普通…

分布式文件系统(FastDFS)

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

吐血整理,接口自动化测试-接口依赖/上传接口处理(项目实例)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 常见的两种接口依…