synchronized 锁升级实现原理

synchronized 锁升级实现原理

对象的内存结构

在HotSpot虚拟机中,对象在内存中存储的布局可分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充

在这里插入图片描述

我们需要重点分析MarkWord对象头

MarkWord
  • hashcode:25位的对象标识Hash码
  • age:对象分代年龄占4位
  • biased_lock:偏向锁标识,占1位 ,0表示没有开始偏向锁,1表示开启了偏向锁
  • thread:持有偏向锁的线程ID,占23位
  • epoch:偏向时间戳,占2位
  • ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针,占30位
  • ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针,占30位

我们可以通过lock的标识,来判断是哪一种锁的等级

  • 后三位是001表示无锁
  • 后三位是101表示偏向锁
  • 后两位是00表示轻量级锁
  • 后两位是10表示重量级锁
2.2.3 再说Monitor重量级锁

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

简单说就是:每个对象的对象头都可以设置monoitor的指针,让对象与monitor产生关联

2.2.4 轻量级锁

在很多的情况下,在Java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步块中的代码。这种情况下,用重量级锁是没必要的。因此JVM引入了轻量级锁的概念。

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

加锁的流程

1.在线程栈中创建一个Lock Record,将其obj字段指向锁对象。

2.通过CAS指令将Lock Record的地址存储在对象头的mark word中(数据进行交换),如果对象处于无锁状态则修改成功,代表该线程获得了轻量级锁。

3.如果是当前线程已经持有该锁了,代表这是一次锁重入。设置Lock Record第一部分为null,起到了一个重入计数器的作用。

4.如果CAS修改失败,说明发生了竞争,需要膨胀为重量级锁。

解锁过程

1.遍历线程栈,找到所有obj字段等于当前锁对象的Lock Record。

2.如果Lock Record的Mark Word为null,代表这是一次重入,将obj设置为null后continue。

3.如果Lock Record的 Mark Word不为null,则利用CAS指令将对象头的mark word恢复成为无锁状态。如果失败则膨胀为重量级锁。

偏向锁

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

Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现

这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有

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

加锁的流程

1.在线程栈中创建一个Lock Record,将其obj字段指向锁对象。

2.通过CAS指令将Lock Record的线程id存储在对象头的mark word中,同时也设置偏向锁的标识为101,如果对象处于无锁状态则修改成功,代表该线程获得了偏向锁。

3.如果是当前线程已经持有该锁了,代表这是一次锁重入。设置Lock Record第一部分为null,起到了一个重入计数器的作用。与轻量级锁不同的时,这里不会再次进行cas操作,只是判断对象头中的线程id是否是自己,因为缺少了cas操作,性能相对轻量级锁更好一些

实现全流程

在java6.0之前我们使用synchronized是为了解决多个线程之间的竞争问题,使用的是重量级锁。其实现是通过监视器Monitor来实现。但在java6之后就引入了偏向锁,轻量级锁,以及重量级锁。下面是锁升级的全流程介绍

首先当一个对象刚被创建在其对象头当中会设置Mark Word信息,Mark Word是用来保存对象的基本信息如hash值,锁信息等。当一个对象刚被创建其状态必然是无锁状态,在对象头的Mark Word当中就会有个所表示用来表示当前状态,无锁为00.当一个线程尝试获取锁时,就会检查Mark Word当中的信息判断其状态,如果为无锁状态就会尝试通过CAS的方式去修改锁表示,在CAS执行成功后同时还会在Mark Word当中储存当前线程的线程ID,之后会在锁的内存当中创建一条所记录用于备份对象头当中的Mark Word信息。

此时如果还有其他线程进入,首先回去判断Mark Word当中的线程ID与自身线程ID是否相同,如果不同则表明出现了锁竞争,jvm会将当前锁升级为轻量级锁。在轻量级锁当中对象的Mark Word会保存一个锁对象的地址指针,线程需要用过CAS的方式去修改这个指针使其指向自己,哪个线程修改成功就可以获取锁。除此之外轻量级锁同偏向锁一样也会在线程内部创建所记录,但是轻量级锁的所记录条数取决于重入次数(只有第一次所记录才会记录对象的Mark Word信息,重入锁的所记录不会记录Mark Word)。

如果其他线程多次尝试获取锁失败,说明当前竞争非常激烈,此时jvm就会将锁升级为重量级锁,重量级锁是通过监视器Monitor实现的,锁对象的对象头会通过Mark Wrld指向一个监视器。在监视器的内部主要包含三个组成,Owner,EntitySet,WaitSet。当线程尝试获取锁的时候就会去检查Owner当中是否为空,如果为空则尝试将Owner与自身线程绑定,即占有了该锁。此时如果还会有线程进入一样需要查看Owner当中是否为空,如果不为空则会被放入EntitySet当中,该结构是用来储存等待的线程的。当Owner线程执行完毕释放锁,就会通过计算机操作系统,通过内核态来唤醒这些线程去抢锁。除此之外对于使用了Wait方法的线程,监视器会将其放入WaitSet队列当中进行等待

Monitor实现的锁属于重量级锁,你了解过锁升级吗?

  • Monitor实现的锁属于重量级锁,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。
  • 在JDK 1.6引入了两种新型锁机制:偏向锁和轻量级锁,它们的引入是为了解决在没有多线程竞争或基本没有竞争的场景下因使用传统锁机制带来的性能开销问题。

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

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

相关文章

vue3实现页签

效果 注意点 useStore涉及的部分是pina的缓存,需要改成自己的;userStore.tabStore是获取缓存里的页签,userStore.$patch(state > { state.tabStore tabStoreList.value }) 是存储改变的页签注意我的页签是根据路由path来判断的&#xf…

dfs算法搜索(详细)

目录 算法简介: 枚举方式: 1.每一个数都有两种状态,也就是选或不选,时间复杂度也就是2^n,每一个数都有选和不选两种状态。 2.生成给定集合所有可能排列的方法,与之不同的是同样是1 2 3三个数字&#xff0…

【机器学习】解构概率,重构世界:贝叶斯定理与智能世界的暗语

文章目录 条件概率与贝叶斯定理:深入理解机器学习中的概率关系前言一、条件概率与贝叶斯定理1.1 条件概率的定义与公式1.1.1 条件概率的定义1.1.2 条件概率的实例讲解 1.2 条件概率的性质与法则1.2.1 链式法则1.2.2 全概率公式1.2.3 贝叶斯定理的推导 1.3 贝叶斯定理…

利用开源Stable Diffusion模型实现图像压缩比竞争方法用更低的比特率生成更逼真的图像

概述 论文地址:https://studios.disneyresearch.com/app/uploads/2024/09/Lossy-Image-Compression-with-Foundation-Diffusion-Models-Paper.pdf 迪士尼的研究部门正在提供一种新的图像压缩方法,利用开源Stable Diffusion V1.2 模型,以比竞…

【Flask+OpenAI】利用Flask+OpenAI Key实现GPT4-智能AI对话接口demo - 从0到1手把手全教程(附源码)

文章目录 前言环境准备安装必要的库 生成OpenAI API代码实现详解导入必要的模块创建Flask应用实例配置OpenAI API完整代码如下(demo源码)代码解析 利用Postman调用接口 了解更多AI内容结尾 前言 Flask作为一个轻量级的Python Web框架,凭借其…

SpringBoot【十三(实战篇)】集成在线接口文档Swagger2

一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 二、如何生成Swagger文档 上一期我们已经能正常访问swagger在线文档,但是文档空空如也,对不对,接下来我就教大家怎么把相关的接口都给…

Qt之自定义动态调控是否显示日志

创作灵感 最近在芯驰x9hp上开发仪表应用。由于需要仪表警告音,所以在该平台上折腾并且调试仪表声音的时候,无意间发现使用: export QT_DEBUG_PLUGINS1 可以打印更详细的调试信息。于是想着自己开发的应用也可以这样搞,这样更方便…

Linux网络 UDP socket

背景知识 我们知道, IP 地址用来标识互联网中唯一的一台主机, port 用来标识该主机上唯一的一个网络进程,IPPort 就能表示互联网中唯一的一个进程。所以通信的时候,本质是两个互联网进程代表人来进行通信,{srcIp&…

数据链路层(Java)(MAC与IP的区别)

以太网协议: "以太⽹" 不是⼀种具体的⽹络, ⽽是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理 层的内容. 例如: 规定了⽹络拓扑结构, 访问控制⽅式, 传输速率等; 例如以太⽹中的⽹线必须使⽤双绞线; 传输速率有10M, 100M, 1000M等; 以太…

Apache APISIX快速入门

本文将介绍Apache APISIX,这是一个开源API网关,可以处理速率限制选项,并且可以轻松地完全控制外部流量对内部后端API服务的访问。我们将看看是什么使它从其他网关服务中脱颖而出。我们还将详细讨论如何开始使用Apache APISIX网关。 在深入讨…

项目15:简易扫雷--- 《跟着小王学Python·新手》

项目15:简易扫雷 — 《跟着小王学Python新手》 《跟着小王学Python》 是一套精心设计的Python学习教程,适合各个层次的学习者。本教程从基础语法入手,逐步深入到高级应用,以实例驱动的方式,帮助学习者逐步掌握Python的…

HTML+CSS+Vue3的静态网页,免费开源,可当作作业使用

拿走请吱一声&#xff0c;点个关注吧&#xff0c;代码如下&#xff0c;网页有移动端适配 HTML <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width…

Python的3D可视化库【vedo】2-1 (plotter模块) 绘制器的使用

文章目录 1 相关用语及其关系2 Plotter类的基本使用3 Plotter类具体的初始化设置3.1 全部初始化参数3.2 使用不同的axes vedo是Python实现的一个用于辅助科学研究的3D可视化库。 vedo的plotter模块封装了绘制器类Plotter。 Plotter实例可以用于显示3D图形对象、控制渲染器行为、…

职业院校人工智能实验室解决方案

随着人工智能技术的迅猛发展&#xff0c;企事业单位对具备高素质技术应用能力的人才需求愈发迫切&#xff0c;目前人工智能已经逐步从感知理解阶段转变为生成创造阶段&#xff0c;可以为各行各业提供多维的智能化应用服务。2024年的《政府工作报告》中首次提出了“人工智能”行…

steel-browser - 专为AI应用构建的开源浏览器自动化 API

Steel是一个开源浏览器 API&#xff0c;可以轻松构建与 Web 交互的 AI 应用程序和代理。您无需从头开始构建自动化基础设施&#xff0c;而是可以专注于 AI 应用程序&#xff0c;而 Steel 会处理复杂性。 2300 Stars 99 Forks 4 Issues 5 贡献者 Apache-2.0 License TypeScript …

ElasticSearch - 使用 Composite Aggregation 实现桶的分页查询

文章目录 官方文档概述Composite Aggregation 概述示例&#xff1a;基本分页查询分页&#xff1a;获取下一页结果使用场景注意事项 官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html#_pagin…

基于Python+Sqlite3实现的搜索和推荐系统

基于Python实现的搜索和推荐系统 一、引言 伴随着科技的不断进步&#xff0c;互联网&#xff0c;万维网的不断发展。我们越来越热爱万维网&#xff0c;也欣赏他的发展方式。20世纪90年代初&#xff0c;万维网还只是一个将文档联系起来的简单网络。如今&#xff0c;他已经成为…

Oracle:VARCHAR2(100)与VARCHAR2(100 CHAR)的差异导致的报错

目录 >> 问题背景&#xff1a;>> 阴差阳错&#xff1a;>> 问题出现&#xff1a;>> 问题排查&#xff1a;>> 知识点&#xff1a;>> 问题复盘&#xff1a;>> 问题拓展&#xff1a; >> 问题背景&#xff1a; Oracle下&#xff1…

右玉200MW光伏电站项目 微气象、安全警卫、视频监控系统

一、项目名称 山西右玉200MW光伏电站项目 微气象、安全警卫、视频监控系统 二、项目背景&#xff1a; 山西右玉光伏发电项目位于右玉县境内&#xff0c;总装机容量为200MW&#xff0c;即太阳能电池阵列共由200个1MW多晶硅电池阵列子方阵组成&#xff0c;每个子方阵包含太阳能…

最短路----Dijkstra算法详解

简介 迪杰斯特拉&#xff08;Dijkstra&#xff09;算法是一种用于在加权图中找到单个源点到所有其他顶点的最短路径的算法。它是由荷兰计算机科学家艾兹格迪科斯彻&#xff08;Edsger Dijkstra&#xff09;在1956年提出的。Dijkstra算法适用于处理带有非负权重的图。迪杰斯特拉…