synchronized锁膨胀过程

轻量级锁:

使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以 使用轻量级锁来优化。

轻量级锁原理

1.创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的 Mark Word

2.让锁记录中 Object reference 指向锁对象,并尝试用 cas 替换 Object 的 Mark Word,将 Mark Word 的值存入锁记录

3. 如果 cas 替换成功,对象头中存储了 锁记录地址和状态 00 ,表示由该线程给对象加锁,这时图示如下

4.如果 cas 失败,有两种情况

a.如果是其它线程已经持有了该 Object 的轻量级锁,这时表明有竞争,进入锁膨胀过程

b.如果是自己执行了 synchronized 锁重入,那么再添加一条 Lock Record 作为重入的计数

当退出 synchronized 代码块(解锁时)如果有取值为 null 的锁记录,表示有重入,这时重置锁记录,表示重 入计数减一

当退出 synchronized 代码块(解锁时)锁记录的值不为 null,这时使用 cas 将 Mark Word 的值恢复给对象头

a.成功,则解锁成功

b.失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁解锁流程

锁膨胀

锁膨胀原理

如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这时一种情况就是有其它线程为此对象加上了轻量级锁(有 竞争),这时需要进行锁膨胀,将轻量级锁变为重量级锁。

static Object obj = new Object();
public static void method1() {
 synchronized( obj ) {
 // 同步块
 }
}

当 Thread-1 进行轻量级加锁时,Thread-0 已经对该对象加了轻量级锁

这时 Thread-1 加轻量级锁失败,进入锁膨胀流程

即为Object 对象申请 Monitor 锁,让 Object 指向重量级锁地址

然后自己进入 Monitor 的 EntryList BLOCKED

当 Thread-0 退出同步块解锁时,使用 cas 将 Mark Word 的值恢复给对象头,失败。这时会进入重量级解锁 流程,即按照 Monitor 地址找到 Monitor 对象,设置 Owner 为 null,唤醒 EntryList 中 BLOCKED 线程

重量级锁:每个 Java 对象都可以关联一个 Monitor 对象,如果使用 synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针

偏向锁

轻量锁缺陷:

轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。

轻量锁优化

static final Object obj = new Object();
public static void m1() {
 synchronized( obj ) {
 // 同步块 A
 m2();
 }
}
public static void m2() {
 synchronized( obj ) {
 // 同步块 B
 m3();
 }
}
public static void m3() {
 synchronized( obj ) {
 // 同步块 C
 }
}

Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现 这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。如下图所示。(偏向第一个获得锁的线程,并把这个线程存储在对象头里,之后只要是该线程来获取锁,都能快速批准)

总结

轻量级锁

栈帧中包含锁记录(Lock Record:lock record 地址;Object reference)

先创建锁记录,Object reference指向锁对象(obect),并通过cas替换lock record地址和objec中的Mark Word(锁记录地址和状态);

如果失败,可能是其他线程持有了该object轻量级锁,则进入锁膨胀;也可能是自己重入,则再添加一条锁记录用来计数,同时该锁记录object reference指向object,lock record为null.

当退出synchronized时,如果发现有null的记录,表明有重入,然后重置锁记录;若不为null,则使用cas还原(Mark word恢复给Object,lock record地址恢复给lock record);如果失败,则表明进入了锁膨胀环节,则进入重量锁解锁过程。

锁膨胀

当Thread1尝试进行轻量级锁,无法cas成功,说明有其他线程(Thread0)给该Object对象上锁,此时轻量级锁升级成重量级锁;为Object对象申请Monitor锁,Object指向该Monitor,然后Thread1会进入Monitor的EntryList中阻塞,而Monitor中的Owner会指向Thread0中lock recotd中Object reference。当Thread0退出Synchronized代码块时,发现使用cas无法解锁成功,Thread0会依据Monitor地址找到Monitor对象,设置Owner为null,然后唤醒EntryList中的Thread1

偏向锁

只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS,因此只需要检查该线程ID是否是自己

 摘自哔哩哔哩黑马程序员笔记

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

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

相关文章

【前端学java】java中的字符串操作(10)

往期回顾: 【前端学java】JAVA开发的依赖安装与环境配置 (0)【前端学 java】java的基础语法(1)【前端学java】JAVA中的packge与import(2)【前端学java】面向对象编程基础-类的使用 &#xff08…

抖音电商双11官方数据最全汇总!

11月13日,抖音电商数据发布“抖音商城双11好物节”数据报告,展现双11期间平台全域经营情况及大众消费趋势。 报告显示,10月20日至11月11日,抖音电商里的直播间累计直播时长达到5827万小时,挂购物车的短视频播放了1697亿…

PEFT LoraConfig参数详解

参数高效微调 (PEFT) 可以使预训练模型高效适应下游应用,而无需微调所有模型参数。 PEFT 支持广泛使用的大型语言模型低秩适应 (LoRA)。 为了从预训练的 Transformer 模型创建 LoRA 模型,我们导入并设置 LoraConfig。 例如, from peft impo…

数据预处理pandas pd.json_normalize占用内存过大优化

问题描述 从ES下载数据,数据格式为json,然后由pandas进行解析,json中的嵌套字段会进行展开作为列名(由于维度初期无法预测,所以根据数据有啥列就使用啥列,这是最方便的点),变成表格,方面了后续…

Proxmox download

Proxmox VE proxmox Virtual Environment是一个基于 QEMU/KVM 和 LXC 的开源服务器虚拟化管理解决方案。您可以使用集成的、易于使用的 Web 界面或通过 CLI 管理虚拟机、容器、高可用性集群、存储和网络。Proxmox VE 代码根据 GNU Affero 通用公共许可证第 3 版获得许可 Prox…

Vue typescript项目配置eslint+prettier

1.安装依赖 安装 eslint yarn add eslint --dev安装 eslint-plugin-vue yarn add eslint-plugin-vue --dev主要用于检查 Vue 文件语法 安装 prettier 及相关插件 yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev安装 typescript 解析器、规则补充 …

Redis篇---第十一篇

系列文章目录 文章目录 系列文章目录前言一、说说Redis持久化机制二、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题三、热点数据和冷数据是什么前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…

gzip 压缩优化大 XML 响应的处理方法

当处理大型XML响应时,我们经常会面临内存限制和性能问题。 在处理这个问题时,我们可以使用Python的requests库和lxml库来解决。下面是解决方案的步骤: 1. 使用requests库发送HTTP请求获取XML响应。 2. 检查响应的Content-Encoding标头&…

这篇文章带你了解:如何一次性将Centos中Mysql的数据快速导出!!!

目录 一.数据库导出 1.首先创建文件以.sql结尾的文件 2.打开名mysq的解压目录,导出数据 3.然后在查看即可 4 需要的软件 MobaXterm 一.数据库导出 1.首先创建文件以.sql结尾的文件 通过 touch ssm.sql (小编) 实际上&#xff1a…

提升办公效率,畅享多功能办公笔记软件Notion for Mac

在现代办公环境中,高效的笔记软件对于提高工作效率至关重要。而Notion for Mac作为一款全能的办公笔记软件,将成为你事业成功的得力助手。 Notion for Mac以其多功能和灵活性而脱颖而出。无论你是需要记录会议笔记、管理项目任务、制定流程指南&#xf…

以makefile的方式在linux上编译代码(小白级别)

作者:爱塔居 作者简介:大四学生,分享自己的学习片段~ 目录 前言 一、创建主要文件 二、makefile 前言 多有不足,以供参考,欢迎大佬们指点。我是在虚拟机上执行的,应该都一样。我用的VirtualBox,…

第十篇 基于JSP 技术的网上购书系统——管理员后台管理主界面、订单管理、产品管理功能实现(网上商城、仿淘宝、当当、亚马逊)

目录 1.管理员后台管理——主界面 1.1功能说明 1.2界面设计 1.3处理流程 2.订单管理 2.1功能说明 2.2界面设计 2.3处理流程 2.4数据来源和算法 2.4.1数据来源 2.4.2查询条件 2.4.3表间关系 2.4.4相关sql实例 3.产品管理 3.1功能说明 3.2界面设计 3.3处理流程…

IF:9.0+期刊被踢除,11月SCI/SSCI期刊目录已更新!

【SciencePub学术】2023年11月20日,科睿唯安更新了Web of Science核心期刊目录。 继上次SCI期刊目录和SSCI期刊目录更新之后,本次11月更新共有5本期刊发生变动: • SCIE:有5本期刊不再被SCIE期刊目录收录,1本SCIE期刊更…

漆包线行业你了解多少?

今天就说说漆包线行业,漆包线是工业电机(包括电动机和发电机)、变压器、电工仪表、电力及电子元器件、电动工具、家用电器、汽车电器等用来绕制电磁线圈的主要材料。 漆包线上游是铜杆行业,下游是各种消费终端,主要是电…

微信小程序从零到发布上线,手把手教学(附精选源码250套)

零基础开发,如何上线小程序源码? 1、微信开发者工具安装 电脑端下载并安装“微信开发者工具” | 附下载地址: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 2、登录微信开发者工具 打开运行微信开发者工具…

知识表示与知识图谱

目录 前言 一、知识与知识表示的概念 二、知识图谱 总结 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如…

【LeetCode:2216. 美化数组的最少删除数 | 贪心】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

iCloud怎么备份照片?答案在这!(详细教程)

苹果公司推出的iCloud云服务是一个非常实用的功能。在我们使用苹果手机的时候,它可以帮助我们备份手机中的照片,以防止数据丢失。 但是,很多用户可能还不知道如何使用iCloud备份照片。icloud怎么备份照片?本文将为大家详细介绍使…

Zynq-Linux移植学习笔记之66- 国产ZYNQ通过裕太PHY8521连接国产交换芯片

1、背景介绍 ZYNQ通过裕太PHY 8521主要连接两种国产交换芯片,一种为盛科的CTC8096,另一种为32所的JEM5396。框图示意如下: 2、硬件状态确认 首先检查phy的模式,确认为SGMII_MAC-RGMII_PHY 可通过读出A001寄存器确认状态 读出来应…

UE5的TimeLine的理解

一直以来,我对动画的理解一直是这样的: 所谓动画,就是可导致可视化内容变化的参数和时间的对应关系。 我不能说这个观点现在过时了,只能说自己狭隘了。因为UE的TimeLine的设计理念真让人竖大拇指。 当我第一次看到TimeLine节点的…