synchronized相关知识

1、对象头Markword

2、锁升级过程

无锁

偏向锁:只有一个线程过来加锁,Markword对应变化:偏向线程ID存储当前线程ID,偏向锁标志位置成1,锁标志位置为01;此后如果当前线程再次获取锁,只需对比偏向线程ID即可:

轻量级锁:当第二个线程过来获取锁,并且获取成功,则升级为轻量级锁,对应Markword变化如下:在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,拷贝对象头的Markword到栈帧的Lock Record,然后将对象头的Markword更新为指向Lock Record的指针,并将Lock Record的owner指针指向对象头的Markword。

重量级锁:轻量级锁获取失败,则升级为重量级锁。底层是通过ObjectMonitor实现的。

3、重量级锁的实现原理

ObjectMonitor定义:

// initialize the monitor, exception the semaphore, all other fields
// are simple integers or pointers
ObjectMonitor() {
	_header       = NULL;
	_count        = 0;
	_waiters      = 0,
	_recursions   = 0;
	_object       = NULL;
	_owner        = NULL;
	_WaitSet      = NULL;
	_WaitSetLock  = 0 ;
	_Responsible  = NULL ;
	_succ         = NULL ;
	_cxq          = NULL ;
	FreeNext      = NULL ;
	_EntryList    = NULL ;
	_SpinFreq     = 0 ;
	_SpinClock    = 0 ;
	OwnerIsThread = 0 ;
	_previous_owner_tid = 0;
}

ObjectMonitor主要有三个队列和一个变量比较重要:

三个队列:_WaitSet:等待池。调用wait()方法的线程会进入此队列,等待线程组成一个双向循环链表:

_cxq:相当于栈结构,先进后出。当执行monitorenter指令获取锁失败,或者调用notify()或者notifyAll()时,根据默认策略(默认policy=2),会把当前线程放入_cxq栈顶(相当于头插)。节点被push 到_cxq 列表之后,还会通过自旋尝试获取锁,如果还是没有获取到锁则通过park将当前线程挂起等待被唤醒。

_EntryList:存放进入或者重新进入时被阻塞的线程,也就是竞争锁失败的线程。当前持有锁的线程执行完毕,唤醒下一个线程时,会根据QMode策略(默认QMode=0)唤醒:如果_EntryList不为空,则从_EntryList中取出线程,执行unpark;如果为空,则将_cxq中的元素按原有顺序插入到_EntryList中,并唤醒第一个线程。也就是当_EntryList为空时,是后来的线程先获取锁;_EntryList不为空,直接从_EntryList中唤醒线程。

执行过程如下:

问:为什么锁池要有两个队列_cxq和_EntryList?

答:1、主要是考虑到性能问题。当前持有锁的线程执行完毕唤醒下一个线程时,会先判断_EntryList是否为空,如果不为空就唤醒头节点,如果为空就唤醒_cxq栈顶结点。而notify()、notiryAll()也会操作_cxq,这样冲突的概率就大大增加,导致性能降低。2、为了防止ABA问题:_cxq栈的操作包含push入栈和pop出栈,这样就会产生ABA问题,把两者分开,_cxq就只有入栈push操作,出栈就只能在持有锁的线程唤醒下一个等待节点时从_EntryList取出,不会出现ABA问题。

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

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

相关文章

《十年国庆游,洞察中国旅游新趋势》

作者:侯炯 一、十年国庆旅游数据总览 过去十年,中国国庆旅游市场呈现出丰富的变化和强劲的发展态势。从接待游客人次来看,2014 年接待国内游客 4.75 亿人次,到 2019 年已增长至 7.82 亿人次,2023 年国内旅游出游人数更…

【预备理论知识——1】深度学习:概率论概述

简单地说,机器学习就是做出预测。 概率论 掷骰子 假设我们掷骰子,想知道看到1的几率有多大,而不是看到另一个数字。 如果骰子是公平的,那么所有六个结果{1,…, 6}都有相同的可能发生, 因此我们可以说 1 发生的概率为1…

【数据结构】图的最小生成树

快乐的流畅:个人主页 个人专栏:《C游记》《进击的C》《Linux迷航》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、最小生成树的概念二、Kruskal算法2.1 思想2.2 实现 三、Prim算法3.1 思想3.2 实现 四、Kruskal和Prim的对比…

container_of 函数的分析

这个函数的目的是, 通过结构体里面的内容 找到 大结构体的 基地址。 函数的原型是:  PTR是指针 type , mem&#xff…

新手上路:Anaconda虚拟环境创建和配置以使用PyTorch和DGL

文章目录 前言步骤 1: 安装 Anaconda步骤 2: 创建新的 Anaconda 环境步骤 3: 安装最新版本的 PyTorch步骤 4: 安装特定版本的 PyTorch步骤 5: 安装最新版本的 DGL步骤 6: 安装特定版本的 DGL步骤 7: Pycharm中使用虚拟环境解释器第一种情况:创建新项目第二种情况&am…

Word办公自动化的一些方法

1.Word部分内容介绍 word本身是带有格式的一种文档,有人说它本质是XML,所以一定要充分利用标记了【样式】的特性来迅速调整【格式】,从而专心编辑文档内容本身。 样式(集) 编号(多级关联样式编号&#xff…

Tomcat系列漏洞复现

CVE-2017-12615——Tomcat put⽅法任意⽂件写⼊漏洞 漏洞描述 当 Tomcat运⾏在Windows操作系统时,且启⽤了HTTP PUT请求⽅法(例如,将 readonly初始化参数由默认值设置为false),攻击者将有可能可通过精⼼构造的攻击请求…

探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾

上周六,第二十一期「Data Infra 研究社」在线上与大家相见。活动邀请到了西门子数据分析师陈砚林与 Databend 联合创始人王吟,为我们带来了一场关于 Snowflake 和 Databend 的技术探索。Snowflake,这个市值曾超过 700 亿美元的云原生数据仓库…

Android 安卓内存安全漏洞数量大幅下降的原因

谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码,尽管旧代码(用 C/C 编写)没有被重写,但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量(来源:谷歌&#xff09…

资质申请中常见的错误有哪些?

在申请建筑资质的过程中,企业可能会犯一些常见的错误,以下是一些需要避免的错误: 1. 资料准备不充分: 申请资质需要提交大量的资料,包括企业法人资料、财务报表、业绩证明等。资料不齐全或不准确都可能导致申请失败。…

汽车线束之故障诊断方案-TDR测试

当前,在汽车布局中的线束的性能要求越来越高。无法通过简单的通断测试就能满足性能传输要求。早起对智能化要求不高,比如没有激动雷达、高清摄像、中央CPU等。 近几年的智能驾驶对网络传输要求越来越高,不但是高速率,还需要高稳定…

【C++题目】7.双指针_和为 s 的两个数字

文章目录 题目链接:题目描述:解法C 算法代码:图解 题目链接: LCR 179.查找总价格为目标值的两个商品 题目描述: 解法 解法一(暴力解法,会超时) 两层 for 循环列出所有两个数字的组合…

一种使用 SUMO + Python 联合仿真平台

一种使用 SUMO Python 联合仿真平台(一) 本文适用人群包括但不仅限于【交通运输】【车辆工程】【自动化控制】【计算机科学与技术】等专业本科生、研究生、博士生。本文通过在Pycharm平台,使用Python语言 Traci工具包,调用SUMO客…

【步联科技身份证】 身份证读取与解析———未来之窗行业应用跨平台架构

一、身份证解析代码 C# function 身份证数据解析_湖南步联科技(wzxx) {var result {};result[xm] wzxx.substr(0, 15);result[xbdm] wzxx.substr(15, 1);result[mzdm] wzxx.substr(16, 2);result[csrq] wzxx.substr(18, 8);result[dzmc] wzxx.substr(26, 35);result[gms…

Ansible-template模块动态生成特定文件

文章目录 一、Jinja2介绍什么是主要特性安装基本用法进阶特性总结 Jinja2与Ansible关系1. 模板引擎2. Ansible 的依赖3. 变量和模板4. 动态生成配置5. 社区和生态系统总结 二、Ansible如何使用Jinja2使用template模块Jinja2文件中使用判断和循环Jinja2文件中使用判断语法 Jinja…

如何在算家云搭建text-generation-webui(文本生成)

一、text-generation-webui 简介 text-generation-webui 是一个流行的用于文本生成的 Gradio Web UI。支持 transformers、GPTQ、AWQ、EXL2、llama.cpp (GGUF)、Llama 模型。 它的特点如下, 3 种界面模式:default (two columns), notebook, chat支持多…

Vue发送邮件攻略:从搭建到实现详细步骤?

vue发送邮件功能实现方法?Vue前端如何实现发送邮件? 随着应用功能的不断扩展,用户交互的复杂性也在增加。其中,发送邮件功能是许多Web应用中不可或缺的一部分。AokSend将详细介绍如何使用Vue.js实现发送邮件功能。 Vue发送邮件&…

Springboot指定扫描路径

方式一:通过在启动类的SpringbootApplication中指定包扫描或类扫描 指定需要扫描的包 scanBasePackages{"待扫描包1","待扫描包2", . . . ," "} 指定需要扫描的类 scanBasePackageClasses{类1.class,类2.class,...} 方式二&#xff…

STM32F103C8----3-1 LED闪烁(跟着江科大学STM32)

一,电路图 接线图 面包板的的使用请参考:《面包板的使用_面包板的详细使用方法-CSDN博客》 二,目的/效果 2.1 推婉输出 外部供电(熄的时间长) 2.2 推婉输出 内部供电(亮的时间长) 三,创建Keil项目 详…

音乐项目总结(终)

总的来说写这个项目还是状态差了,前期中期写太慢,后期疯狂赶。 讲点对写这个项目能想起来解决的问题和写的的感触。 前期:当时觉得时间很充足,有布置算法题,我竟然还花三四天去学算法,,动态规划…