synchronized锁升级过程

news2024/12/23 22:10:53

【一些面试真题】:

在这里插入图片描述
阿里P9——0x80的执行过程。

【 重温CAS过程 】:

【硬件】:
Lock指令在执行后面指令的时候锁定一个北桥信号(不采用锁总线的方式)。

【用户态 与 内核态】:

作为操作系统来说,它能够做的操作是不允许普通程序去做的。为了保障操作系统的健壮性,现代的操作系统都会把指令分成级别。
内核态是执行在内核空间的,它能够访问所有的指令。
而用户态的程序只能访问用户能够访问的指令。
在这里插入图片描述
在这里插入图片描述
//对于操作系统来说 , 你JVM也仅仅是工作在用户态的。
【 重量级锁 】:
锁这个资源是需要通过操作系统才能够去申请到的。称之为重量级锁的原因是——申请、返回 都需要经过操作系统。
【 早期上重量级锁 】:
JVM要对某个资源加锁了 ,你对资源加锁的时候 , 你得向操作系统申请一把锁——完成从用户态到内核态的调用。
【中断的调用】:
从JVM到OS申请的时候,是要经过一个中断的调用。返回锁的时候,也是要从内核态返回到用户态。
【做的优化】:

某些状态下上锁的话 , 是无需向操作系统申请的,只需要在用户态就可以解决问题。

【JOL对象内存布局】:

JOL = Java Object Layout

一个对象在内存中如何分布这件事情,是和特定的JVM虚拟机实现有关系的,我们今天讲的主要是Hotspot的实现 ,其它的虚拟机有可能不是这种实现。

【四部分构成】:

markword 8、 classpointer 4 、 instance data(看实际的变量类型)、 padding(补齐)。

【markword中】:

其中,最重要的信息就是——锁信息。

【详解锁升级过程】:

在这里插入图片描述

【锁升级实质】:

通过markword的后几位标志来实现升级的;

【锁升级图】:

锁升级初步

在这里插入图片描述
//当我们new出一个普通对象的时候,它有可能是两种状态,两种状态的意思是——普通对象/匿名偏向 两种类型的markword是不同的形式,new Object就是一个普通对象。

【new Object】:

我们new Object , 一旦我给这个对象加上了synchronized关键字的时候 , 它会首先升级成偏向锁 ,竞争一旦激烈就会升级成轻量级锁,轻量级锁又叫做自旋锁,竞争再加剧会变成重量级锁——也就是一开始我们提到的,向操作系统老大申请的锁。

【偏向锁未启动】:

在这里插入图片描述
偏向锁没有启动 , 普通对象也是有可能直接升级成轻量级锁的。

【 如何区分锁的状态 】:

在这里插入图片描述
00——轻量级锁;
10——重量级锁;
11——GC标记信息;
在这里插入图片描述
01——必须得靠偏向锁位来区分。
001——无锁状态。
101——偏向锁状态。

【锁的介绍】:

【用户空间锁】:

偏向锁 和 轻量级锁 都是用户空间锁(用户态度锁)—— 我不需要和操作系统打交道。

【重量级锁VS用户空间锁】:

在这里插入图片描述
//偏向锁——哪个线程先来,我就偏向它就可以了。

【StringBuffer】:

里面的方法是全都加synchronized的。

【形象理解锁机制】:

在这里插入图片描述

【偏向锁】:

markWord中放的是当前线程指针,所谓的偏向锁是没有必要设计锁竞争机制的,第一个访问这把锁的线程直接把自己的线程ID往上一贴就完了。总而言之是贴上当前线程的标志。

【自旋锁】:

先撤销偏向锁之前贴上的线程标识 ,撤销掉之后进行竞争 ,竞争的方式就是——自旋的竞争 ;
在这里插入图片描述

LockRecord

每个线程在它的线程栈中生成一个LR(锁记录),将这个LR贴到锁上,锁上的指针指向哪一个线程的LR , 就表示哪个线程持有这把锁。另外的线程只能用CAS机制继续竞争。

【重量级锁】:

//我这把锁必须得向操作系统去申请;MarkWord中实际记录的是一个ObjectMoint——实际就是JVM空间写的一个C++对象 , 而这个C++对象它内部去访问的时候是需要通过操作系统,经过操作系统之后拿到操作系统对应的那一把锁。

【Hotspot源码位置】:

在这里插入图片描述
InterpreterRuntime::monitorenter方法。
在这里插入图片描述

【synchronized编译过程】:

当我们在Java文件中写了synchronized{…} 代码块之后,在汇编语句中就会出现:
monitorenter——原 { 位置处,锁开始。
monitorexit—–—原 } 位置出,锁结束。
最后一个monitorexit—–—产生任何异常的话。
在这里插入图片描述
//最后一个monitorexit是表示——产生了异常,如果发生异常自动释放锁。

【monitorenter】:

在这里插入图片描述
在这里插入图片描述
//如果使用了偏向锁 ( 618行的判断 ), 也就是如果偏向锁打开了 ,fast_enter——快速地竞争锁;否则slow_enter。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//首先进入自旋;——升级为自旋锁。

//如果自旋锁不成——锁膨胀。inflate方法——膨胀为重量级锁。

【重量级锁的代码】

synchronizer.cpp 中。

【 锁重入 】:

sychronized是可重入锁。
重入次数必须记录,因为要解锁几次必须得对应。
重入次数记录在哪里呢???
——不同锁的实现是不一样的,偏向锁记录在线程栈里,每增加一次,LR+1。
偏向锁、自旋锁 -> 线程栈 -> LR+1 。
重量级锁 -> ObjectMonitor 字段上。

【概念简介】:

在这里插入图片描述
方法m( ) 是 synchronized 修饰的 ,方法m加的锁是O , 方法m里面调用了方法 n( ) , 方法n( ) 加的锁也是O , 所以就相当于给锁O上了两次。

【自旋锁什么时候升级成重量级锁?】:

竞争加剧,有线程超过10次自旋,或者自旋线程数超过CPU核数的一半。
在这里插入图片描述

【 偏向锁启动 】:

【为什么有自旋锁还需要重量级锁?】:

自旋是消耗CPU资源的,如果锁的时间长,或者自旋线程多,CPU会被大量消耗。
//时间都花在线程的自旋上了。
重量级锁里面有各种各样的队列。每个队列的作用都是不同的(竞争 / 执行 / 等待)。
一个线程想申请一把重量级锁,会进入一个队列里。假如10000个线程在等待,这10000个线程会在WaitSet里 ,不需要消耗CPU时间,所以在竞争超级激烈的时候重量级锁会比自旋锁更合适。Linux内核对于进程的调度叫做CFS 。
重量级锁有等待队列,所有拿不到锁的进入等待队列,不需要消耗CPU资源。

【偏向锁是否一定比自旋锁效率高?】:

不一定。
在明确知道会有多线程竞争的情况下,偏向锁肯定会涉及锁撤销,这时候直接关闭偏向锁,这时候直接使用自旋锁。
JVM启动过程,会有很多线程竞争(明确),所以默认情况启动时不打开偏向锁,过一段儿时间再打开。
在这里插入图片描述
//偏向锁启动的时候,默认有一个时延。

【匿名偏向】:

刚开始偏向锁还没有偏向任何一个线程,所以称之为匿名偏向。

【 偏向锁直接升级成重量级锁 】:

调用了wait( ) 方法,直接进入重量级锁状态。

【所有锁升级路线】:

  • new -> 普通对象
  • 普通对象 -> 轻量级锁
  • new -> 匿名偏向
  • 匿名偏向 -> 偏向锁
  • 偏向锁 -> 轻量级锁
  • 偏向锁 -> 重量级锁
  • 轻量级锁 -> 重量级锁
    在这里插入图片描述

【普通对象到偏向锁】:

关键在于——Epoch。( 批量重偏向与批量撤销 )
在这里插入图片描述
在这里插入图片描述

【例】:

一个Class , 有很多的对象( 1~19 )。
在这里插入图片描述
//第一个线程来的时候,会把锁全都给加上。( 20个同一个类的对象 )
在这里插入图片描述
第二个线程来竞争这个锁的时候——它会直接升级成为《自旋锁》。从第21个对象开始,如果线程又给这个对象来上锁,上的会是偏向锁。——这个锁叫做重偏向。因为它原先偏向过第一个线程,批量重偏向。本来这个锁已经升级到了《轻量级锁》 ,JVM观测到你这个Class对应的对象竞争非常的多,这个时候给你又回到偏向锁这种效率比较高的机制上来 ,这个优化是针对于Class来进行的,它并不是针对于对象进行的,前面讲的都是针对于对象来讲的,而这个优化是针对于Class来说的,线程继续加锁 , 当加到第41个的时候,我认为加偏向锁是有问题的,这个时候就会进行批量锁撤销,会把你以前锁定的这些全部撤销,全升级为《自旋锁》。———批量锁的重偏向、批量锁的撤销。

[ 复习批量重偏向 、批量锁撤销 概念 ]:

在这里插入图片描述
Class生产的所有对象 ,把你对象的状态全部都换成偏向锁。
如果说你的对象特别多 ,说明竞争非常激烈 ,到第40个的时候,全部给你换成轻量级锁。
//这是一个针对Class的操作。

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

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

相关文章

WebRTC学习笔记二 基础概念

一、WebRTC与架构 简单来说,WebRTC 是一个可以在 Web 应用程序中实现音频,视频和数据的实时通信的开源项目。在实时通信中,音视频的采集和处理是一个很复杂的过程。比如音视频流的编解码、降噪和回声消除等,但是在 WebRTC 中&…

C. Strange Test(位运算或)

Problem - 1632C - Codeforces 伊戈尔正在读11年级。明天他将不得不写一份信息学测试&#xff0c;由学校最严格的老师帕维尔-杰尼索维奇负责。 伊戈尔知道测试将如何进行&#xff1a;首先&#xff0c;老师会给每个学生两个正整数a和b&#xff08;a<b&#xff09;。之后&…

[2022-11-28]神经网络与深度学习 hw10 - LSTM和GRU

contentshw10 - LSTM 和GRU相关习题task 1题目内容题目分析题目解答题目总结task 2题目内容题目分析题目解答题目总结task 3题目内容题目分析题目解答题目总结task 4题目内容题目分析题目解答问题总结hw10 - LSTM 和GRU相关习题 task 1 题目内容 当使用公式htht−1g(xt,ht−…

Linux系统中利用C语言控制LED的方法

大家好&#xff0c; 今天主要和大家聊一聊&#xff0c;如何利用C语言控制LED灯的实验。 目录 ​第一&#xff1a;C语言板控制LED灯简介 第二&#xff1a;实验程序实现 ​第三&#xff1a;C语言实验控制程序 ​第一&#xff1a;C语言板控制LED灯简介 实际工作中很少会使用到汇…

分离变数法

今天是2022年11月28号 我的方程学的不太好&#xff0c;一些讲宇宙的&#xff0c;讲技术的&#xff0c;方程实在是看不懂很多方程的解与参数不可分割期末来了 有的人回去了有的人要看光学了我呢&#xff0c;已经废物了&#xff0c;节日快乐&#xff0c;大家伙节日快乐啊&#xf…

Spirng 痛苦源码学习(二)——手写spring大致总框架(一)

文章目录前言一、总体步骤如下1、spring 文件夹2、myProject 文件夹二、主要coding1、配置文件2、容器3、一些spring中的重要的注解4、项目中的使用5.重要的bean定义信息6、postProcessor重要&#xff0c;前置通知和后置主要项目的截图前言 本文主要基于spring的注解的方式完成…

Spring相关源码解读

框架1.ApplicationContext refresh的流程2.spring bean 的生命周期3.spring事务失效的几种场景以及原因4.springMVC执行流程5.一些注解&#xff08;1&#xff09;Configuration&#xff08;2&#xff09;Import&#xff08;3&#xff09;SpringBootApplication6.spring中有哪些…

BP神经网络详解,Python实现求解异或问题

BP神经网络 符号及其含义 nln_lnl​表示第lll层神经元的个数&#xff1b;f(⋅)f()f(⋅)表示神经元的激活函数&#xff1b;W(l)∈Rni∗ni−1W^{(l)}\in\mathbb R^{n_i*n_{i-1}}W(l)∈Rni​∗ni−1​表示第l−1l-1l−1层到第lll层的权重矩阵&#xff1b;wij(l)w_{ij}^{(l)}wij(l…

基于tensorflow的ResNet50V2网络识别动物

前言 之前很多人在&#xff0c;如何进行XXX的识别&#xff0c;对应的神经网络如何搭建。对应神经网络怎么搭建&#xff0c;我也是照本宣科&#xff0c;只能说看得懂而已&#xff0c;没有对这块进行深入的研究&#xff0c;但是现在tensorflow&#xff0c;paddle这些工具&#x…

长期稳定的项目—steam搬砖

大家好&#xff0c;我是阿阳 steam搬砖项目一直稳稳定定的进行着&#xff0c;有些朋友基本都观察了近2年 所以很多人问我公众号的项目是不能做了吗&#xff1f;怎么最近做新的去了&#xff1f;很明显这是几乎不可能的事情&#xff0c;steam做2年了&#xff0c;本公众号都能翻到…

这几个数据分析项目,让我看到了什么才叫专业!!

大家好&#xff0c;我是小一 新的一周又来了&#xff0c;从今天开始&#xff0c;会出一个新的系列《数分实验室》 实验室会介绍一些有内核、有科技的数据分析实战项目。 项目数据集、源代码都是公开的&#xff0c;非常适合想练手但是又没数据、没参考案例的同学 今天先热热…

ES的基础概念

1、ES是什么 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单&#xff0c;它不仅包括了全文搜索功能&#xff0c;还可以进行以下工作:分布式实时文件存储&am…

6-1分支限界法

6-1分支限界法 1.分支限界法与回溯法的不同 &#xff08;1&#xff09;求解目标: 回溯法的求解目标是找出解空间树中满足约束条件的所有解&#xff08;或一个最优解&#xff09;&#xff0c; 而分支限界法的求解目标则是找出满足约束条件的一个解&#xff08;或最优解&#x…

组织机器学习代码

组织机器学习代码 从note本转移到 Python 脚本时组织代码。 Intuition 有组织的代码就是有可读的、可重现的、健壮的代码。您的团队、经理&#xff0c;最重要的是&#xff0c;您未来的自己&#xff0c;将感谢您为组织工作付出的最初努力。在本课中&#xff0c;将讨论如何将代码…

pytest测试框架入门1

pytest单元测试框架 单元测试是指在软件开发当中&#xff0c;针对软件的最小单位&#xff08;函数&#xff0c;方法&#xff09;进行正确性的检查测试 单元测试框架主要做什么 测试发现&#xff1a;从多个文件里面找到我们的测试用例测试执行&#xff1a;按照一定的顺序和规则…

初学者指南: 使用NumPy数组进行图像处理

这里写自定义目录标题初学者指南: 使用NumPy数组进行图像处理1、加载图像2、裁剪图像3、分离颜色4、转换5、灰度转换6、图像分割结语初学者指南: 使用NumPy数组进行图像处理 由于图像也可以被视为由数组组成&#xff0c;因此我们也可以使用NumPy执行不同的图像处理任务。在本文…

【Lilishop商城】No2-6.确定软件架构搭建五(本篇包括定时任务xxl-job)

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇只介绍重点架构逻辑&#xff0c;具体编写看源代码就行&#xff0c;读起来也不复杂~ 谨慎&#xf…

如何配置一台适合oc渲染器的电脑?

众所周知&#xff0c;Octane 是最流行的渲染引擎之一。此外&#xff0c;Octane 是一个 GPU 渲染引擎&#xff0c;它使用一种计算最终生成的图片的方法&#xff0c;试图达到照片般的真实感。Octane 是一种利用 GPU 技术的无偏渲染引擎&#xff0c;非常接近物理精度。一台好的 PC…

计算机组成原理习题课第三章-2(唐朔飞)

计算机组成原理习题课第三章-2&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

天宇优配|平台助企“抱团出海” “小而美”中觅“先机”

天津华图轿车物流有限公司一批二手新能源车从连云港装船发往阿联酋迪拜。&#xff08;采访方针供图&#xff09; 最近&#xff0c;一笔100.8万美元的出口信誉稳妥保单融资借款&#xff0c;被划到了天津华图轿车物流有限公司的账户上。正值客户“下单”高峰期&#xff0c;这笔及…