synchronized 底层是如何实现的 ?

目录

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 监控集合中的所有的线程尝试获取锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pycharm中配置conda

安装好pycharm和conda后&#xff0c;打开pycharm&#xff1a;

贴吧照片和酷狗音乐简单爬取

爬取的基本步骤 很简单&#xff0c;主要是两大步 向url发起请求 这里注意找准对应资源的url&#xff0c;如果对应资源不让程序代码访问&#xff0c;这里可以伪装成浏览器发起请求。 解析上一步返回的源代码&#xff0c;从中提取想要的资源 这里解析看具体情况&#xff0c;一…

Azure添加网络接口

添加网络接口的意义 在 Azure 上&#xff0c;为虚拟机添加网络接口的意义包括以下几个方面&#xff1a; 扩展网络带宽&#xff1a;通过添加多个网络接口&#xff0c;可以增加虚拟机的网络带宽&#xff0c;提高网络传输速度和数据吞吐量。实现网络隔离&#xff1a;每个网络接口…

科东软件受邀参加第五届国产嵌入式操作系统技术与产业发展论坛

8月12日&#xff0c;第五届国产嵌入式操作系统技术与产业发展论坛暨嵌入式系统联谊会主题讨论会&#xff08;总第29次&#xff09;在杭州成功举行。这次论坛的主题是“面向异构多核智能芯片的混合关键系统研究与应用”&#xff0c;上午是“嵌入式异构多核智能芯片产业发展”的主…

Python中的字符串与字符编码

Hello&#xff0c;这里是Token_w的博客&#xff0c;欢迎您的到来 今天文章讲解的是Python中的字符串与字符编码&#xff0c;其中有基础的理论知识讲解&#xff0c;也有实战中的应用讲解&#xff0c;希望对你有所帮助 整理不易&#xff0c;如对你有所帮助&#xff0c;希望能得到…

uniapp-----封装接口

系列文章目录 uniapp-----封装接口 uniapp-----分包 文章目录 系列文章目录 uniapp-----封装接口 uniapp-----分包 文章目录 前言 一、技术 二、封装步骤 1.准备 ​编辑 2.代码填充 request.js&#xff1a; api.js&#xff1a; min.js 页面使用 总结 前言 uni…

Java反序列化漏洞笔记

前言 作为Java安全方面的盲对Java反序列化各种链方面了解的并不多&#xff0c;但是这些链条又极为重要&#xff0c;有助于更好的理解各种漏洞的产出和原理&#xff0c;因此以下笔记开始从底慢慢学起。 为什么会产生安全问题&#xff1f; 服务器反序列化数据时&#xff0c;客…

【数学建模】--灰色关联分析

系统分析: 一般的抽象系统&#xff0c;如社会系统&#xff0c;经济系统&#xff0c;农业系统&#xff0c;生态系统&#xff0c;教育系统等都包含有许多种因素&#xff0c;多种因素共同作用的结果决定了该系统的发展态势。人们常常希望知道在众多的因素中&#xff0c;哪些是主要…

数据结构--最短路径 Dijkstra算法

数据结构–最短路径 Dijkstra算法 Dijkstra算法 计算 b e g i n 点到各个点的最短路 \color{red}计算\ begin\ 点到各个点的最短路 计算 begin 点到各个点的最短路 如果是无向图&#xff0c;可以先把无向图转化成有向图 我们需要2个数组 final[] &#xff08;标记各顶点是否已…

webpack 创建VUE项目

1、安装 node.js 下载地址&#xff1a;https://nodejs.org/en/ 下载完成以后点击安装&#xff0c;全部下一步即可 安装完成&#xff0c;输入命令验证 node -vnpm -v2.搭建VUE环境 输入命令&#xff0c;全局安装 npm install vue-cli -g安装完成后输入命令 查看 vue --ver…

宋浩线性代数笔记(五)矩阵的对角化

本章的知识点难度和重要程度都是线代中当之无愧的T0级&#xff0c;对于各种杂碎的知识点&#xff0c;多做题复盘才能良好的掌握&#xff0c;良好掌握的关键点在于&#xff1a;所谓的性质A与性质B&#xff0c;是谁推导得谁~

深入理解epoll

文章目录 概述1. epoll_create - 创建一个epoll实例2. epoll_ctl - 控制epoll实例的事件结构体介绍events取值&#xff1a;data&#xff1a; 联合体&#xff08;共用体&#xff09;&#xff1a; 3. epoll_wait - 等待事件发生伪代码总结 概述 在网络编程中&#xff0c;高效地处…

人大进仓数据库ksql命令基础

测试环境信息: 系统为银河麒麟V10 数据库为Kingbase ES V8 数据库安装目录为/opt/Kingbase/ES/V8 ksql命令位于/opt/Kingbase/ES/V8/Server/bin下 使用--help获取帮助 续上图 1.查看数据库列表 ./ksql -U system -l 2.查看数据库版本 ./ksql -V 3.连接指定的数据库tes…

浅谈SMT行业MES系统生产管理的特点

一、SMT生产车间在电子制造中起重要作用的部分&#xff0c;主要具备以下生产特点&#xff1a; 1.高密度和高速度&#xff1a; SMT生产车间中的电子元器件一般来说较为精小&#xff0c;且被紧密地排列在PCB上。这就要求SMT生产车间的机械设备具备高精度和高速度&#xff0c;确保…

新增守护进程管理、支持添加MySQL远程数据库,支持PHP版本切换,1Panel开源面板v1.5.0发布

2023年8月14日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.5.0版本。 在这个版本中&#xff0c;1Panel新增了守护进程管理功能&#xff1b;支持添加MySQL远程数据库&#xff1b;支持添加FTP/S和WebDAV的SFTP服务&#xff1b;支持PHP版本切换。此外&am…

Android app专项测试之耗电量测试

前言 耗电量指标 待机时间成关注目标 提升用户体验 通过不同的测试场景&#xff0c;找出app高耗电的场景并解决 01、需要的环境准备 1、python2.7(必须是2.7&#xff0c;3.X版本是不支持的) 2、golang语言的开发环境 3、Android SDK 此三个的环境搭建这里就不详细说了&am…

LeetCode 36题:有效的数独

题目 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff…

8.14 ARM

1.练习一 .text 文本段 .global _start 声明一个_start函数入口 _start: _start标签&#xff0c;相当于C语言中函数mov r0,#0x2mov r1,#0x3cmp r0,r1beq stopsubhi r0,r0,r1subcc r1,r1,r0stop: stop标签&#xff0c;相当于C语言中函数b stop 跳转到stop标签下的第一条…

如何给 Keycloak 用户加上“部门”、“电话”等自定义属性

Keycloak 是一款开源的用户认证和授权软件。在默认安装情况下&#xff0c;它只给新创建的用户提供了 email 属性&#xff0c;但是在许多应用场景中&#xff0c;客户都会要求给新创建的用户增加诸如“部门”、“电话”等自定义属性。 本文会介绍如何给 keycloak 中新创建的用户…

应用 - 行为分析篇

前言 以商超项目为例&#xff0c;为了更好的给用户提供服务&#xff0c;我们需要了解到用户喜欢什么&#xff0c;我的产品中哪些是用户感兴趣的&#xff0c;哪些是不感兴趣的。我应该在推荐栏目中给用户推荐的内容是哪些。 基于这些业务场景&#xff0c;我们需要一套行为分析…