描述一下锁的四种状态及升级过程?

news2024/9/20 22:35:31

文章目录

  • 1、锁的四种状态
  • 2、Java对象头描述
  • 3、锁的升级过程(Synchronized加锁/膨胀流程)
    • 1)简单过程如下图
    • 2)详细过程
      • (1)偏向锁
      • (2)轻量级锁
      • (3)重量级锁
  • 4、拓展
    • 1)synchronized效率低?
    • 2)为什么要有偏向锁?
    • 3)为什么要有重量级锁?
    • 4)偏向锁是否一定比自旋锁效率高?
    • 5)锁重入
    • 6)Hopspot对象头就是MarkWord?
    • 7)锁可以降级?
    • 8)锁对比,适用场景?

1、锁的四种状态

无锁、偏向锁、轻量级锁、重量级锁

2、Java对象头描述

以下为32位对象头描述
在这里插入图片描述以下为64位对象头描述
在这里插入图片描述

3、锁的升级过程(Synchronized加锁/膨胀流程)

1)简单过程如下图

在这里插入图片描述

2)详细过程

当线程访问同步代码块时,首先判断当前锁状态是否为可偏向状态(对象头中偏向锁=1,锁标志=01)
在JDK1.6以上默认开启,开启后程序启动几秒后才会被激活

(1)偏向锁

如果是可偏向状态,检查MarkWord存储的是否是当前线程ID

  • 是,获得偏向锁,执行同步代码块
  • 不是,CAS操作竞争锁,替换线程ID
    • 替换成功,MarkWord的线程ID设置为当前线程ID(线程复用),执行同步代码块
    • 替换失败,锁撤销,升级为轻量级锁
      同一类对象多次撤销升级达到阈值20,则偏向锁认为,后面的锁需要重新偏向新的线程(批量重偏向)
      如果阈值达到40次,则偏向锁认为偏向锁撤销过于频繁,后面直接使用轻量级锁

(2)轻量级锁

升级为轻量级锁的情况

  • 如果不是可偏向状态,直接升级为轻量级锁
  • 偏向锁撤销次数过多

加锁时,会在当前线程栈帧中划出一块空间,作为该锁记录,并且将锁对象MarkWord复制到该锁记录中,CAS操作将MarkWord更新为该锁记录的指针,锁记录中的owner指针指向对象头的MarkWord。

  • 更新成功,MarkWord锁标志位为00,表示轻量级锁状态
  • 更新失败,检查锁对象MarkWord是否指向当前线程栈帧中的锁记录
    • 是,表示锁重入,在当前线程栈帧中锁记录+1
    • 否,自旋等待(默认10次),等待次数达到阈值,升级为重量级锁

(3)重量级锁

升级为重量级锁的情况

  • 竞争加剧,CAS自旋到一定次数升级为重量级锁
  • 自旋线程数超过CPU核数的一半, 1.6之后,加入自适应自旋Adapative Self Spinning,JVM自己控制

获取锁成功,进入EntryList(获取锁的缓冲区、入口)

  • 在调用wait方法后,会进入等待唤醒队列(WaitSet)等待
  • 在调用notify方法后,则可能进入EntryList
    获取锁失败,进入一个等待拿锁队列(cxq)等待

具体重量级锁加锁过程:
1、分配⼀个ObjectMonitor对象,把MarkWord锁标志置为‘10’,然后MarkWord存储指向ObjectMonitor对象的指针。ObjectMonitor对象有两个队列和⼀个指针,每个需要获取锁的线程都包装成ObjectWaiter对象
2、多个线程同时执行同⼀段同步代码时,ObjectWaiter先进⼊EntryList队列,当某个线程获取到对象的monitor以后进⼊Owner区域,并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count+1

说明:
monitor:每个Java对象都有一把锁,称为内部锁或monitor锁
owner,指向的是当前获得线程的地址,用来判断当前锁是被哪个线程持有

4、拓展

1)synchronized效率低?

用户态:偏向锁、轻量级锁
内核态:重量级锁

首先来了解下synchronized重量级锁实现原理?
  通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本质又是依赖于底层的操作系统的 Mutex Lock(互斥锁)来实现的。而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高。
  在JDK6以前,只有重量级锁,阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态切换需要耗费处理器时间。
  在JDK6中,为了提高性能,引入了偏向锁和轻量级锁。

2)为什么要有偏向锁?

大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了减少线程获得锁的代价,所以引入了偏向锁

3)为什么要有重量级锁?

自旋锁消耗CPU资源,重量级锁有等待队列,不会消耗CPU资源

4)偏向锁是否一定比自旋锁效率高?

不一定,在多线程竞争情况下,偏向锁会涉及锁撤销,这时候应该直接使用自旋锁

5)锁重入

重入次数必须记录,才能知道要解锁几次

  • 轻量级锁,记录在线程栈,每插入一次,LockRecord+1
  • 重量级锁,记录在ObjectMonitor字段上

6)Hopspot对象头就是MarkWord?

不是的,Hopspot对象头主要包括两部分数据:MarkWord(标记字段) 和 classPointer(类指针)

7)锁可以降级?

不行的,是一个不可逆的过程,主要是为了提高获得锁和释放锁的效率

8)锁对比,适用场景?

偏向锁:适用于一个线程,不会有锁消耗,锁撤销
轻量级锁:适用于多个线程竞争,但同步代码块执行快的情况下,因为自旋会消耗CPU
重量级锁:适用于多个线程竞争,但同步代码块执行慢的情况下,不消耗CPU,可以提高吞吐量

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

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

相关文章

SpringBoot下的Spring框架学习(Tedu)——DAY02

SpringBoot下的Spring框架学习(Tedu)——DAY02 目录SpringBoot下的Spring框架学习(Tedu)——DAY02Spring框架学习1.1 Spring介绍1.2 知识铺垫1.2.1 编辑Dog类1.2.2 编辑Cat类1.2.3 编辑测试类User.java1.2.4 上述代码的总结1.3 面…

PPQ库中KLD算法实现代码解析

PPQ量化工具库KLD算法解析前言PPQ算法实现NVIDIA的PPT中KLD算法流程KLD算法PPQ实现版本PPQ与NVIDIA的区别:前言 这是对PPQ库中KLD算法实现代码解析,关于PPQ库安装与使用详情见专栏上一篇博客。 PPQ算法实现 nvidia发布的PPT:8-bit Inferen…

使用vue-element-admin进行二次开发

vue-element-admin 介绍 基于 vue 和 element-ui实现 的后台前端解决方案 集成方案: vue-element-admin基础模板: vue-admin-template桌面终端: electron-vue-adminTypescript 版: vue-typescript-admin-template Others: awesome-project 亮点 i18 国际化解决方案 动态路由…

射频功率放大器在辉光放电特征及风速测量原理中的应用

实验名称:辉光放电特征及风速测量原理研究方向:辉光放电测试设备:信号发生器、ATA-8202射频功率放大器,热成像仪、万用表、等离子体传感器实验过程:在等离子体形成条件和流场响应机制的基础上,可以明确影响…

node使用支付宝沙箱模拟支付-好文

首页打开支付宝官方进行登录:支付宝开放平台 (alipay.com)下载支付宝提供的秘钥转化工具:密钥工具下载 - 支付宝文档中心 (alipay.com)打开工具生成密码:然后在支付宝页面配置秘钥开始配置nodenpm init -y初始化,再npm i express跟…

<Linux>进程间通信--管道

前言😃😃😃进程间通信的方式管道 - Linux原生提供2SystemV - 多线程单机通信posix - 多线程网络通信这里我们主要是介绍一下管道一、生活和计算机中的管道😜生活中的管道特点都是有出口和入口的都是单向传输内容的(例如&#xff1…

雨水情测报设施包含哪些设备?

通常雨水情测报及大坝安全监测设施,主要包括:大坝安全监测终端、雨水情监测终端、GNSS监测站、雷达水位计、大坝安全监测平台、雨水情测报系统平台等产品。雨水情测报及大坝安全监测系统方案解决方案雨水情测报及大坝安全监测系统解决方案,主…

华为OD机试题,用 Java 解【字符串加密】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…

Raft图文详解

Raft图文详解 refer to: Raft lecture (Raft user study) - YouTube Raft PDF Raft算法详解 - 知乎 (zhihu.com) 今天来详细介绍一下Raft协议 Raft是来解决公式问题的协议,那么什么是共识呢? 在分布式系统里面,consensus指的是多个节点对…

UEFI移植LVGL

自己组装过游戏主机的应该都有看到过,进入BIOS设置,酷炫的界面便呈现在眼前,而很多BIOS,使用的还是标准的界面。现在有个趋势,phoenix和insyde也在慢慢朝这种GUI界面发展,而AMI的使用C编写的界面已经非常完…

spring学习3.5

Bean是什么 Spring里面的Bean就类似是定义的一个组件,而这个组件的作用就是实现某个功能的,这里所定义的Bean就相当于给了你一个更为简便的方法来调用这个组件去实现你要完成的功能。 IoC是什么 谁控制谁,控制什么? 传统Java SE程…

11.SpringSecurity基于JWT实现Token的处理

SpringSecurity基于JWT实现Token的处理 前面介绍了手写单点登录和JWT的应用,本文结合SpringSecurity来介绍下在SpringBoot项目中基于SpringSecurity作为认证授权框架的情况下如何整合JWT来实现Token的处理。 一、认证思路分析 SpringSecurity主要是通过过滤器来实现…

【JavaWeb】从输入URL到展示出页面的过程

目录 DNS域名解析 检查hosts文件 查询缓存 查询本地DNS服务器 ​编辑查询根域名服务器等 三次握手建立连接 发送请求 响应请求 页面渲染 断开连接 这些过程简单的理解为先找到某人地址,给他发送消息可以去他家拿东西吗?他同意后拿到他的东西在…

33- PyTorch实现分类和线性回归 (PyTorch系列) (深度学习)

知识要点 pytorch最常见的创建模型的方式, 子类 读取数据: data pd.read_csv(./dataset/credit-a.csv, headerNone) 数据转换为tensor: X torch.from_numpy(X.values).type(torch.FloatTensor) 创建简单模型: from torch import nn model nn.Sequential(nn.Linear(15, 1…

Dockerfile简单使用入门

什么是 Dockerfile? Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。 例如&#xff1…

亚马逊电动水泵UL778测试报告

电动水泵UL778如何办理? 近期亚马逊在3C品类吹的风可够大的,严查起UL测试报告了。许多卖家反映收到相关邮件通知,产品也由于在规定时间内无法提供UL测试报告,出现被暂停销售、listing被下架等问题。 从亚马逊此次的动作来看&…

深度学习卷积神经网络CNN之 VGGNet模型主vgg16和vgg19网络模型详解说明(理论篇)

1.VGG背景 2. VGGNet模型结构 3. 特点(创新、优缺点及新知识点) 一、VGG背景 VGGNet是2014年ILSVRC(ImageNet Large Scale Visual Recognition Challenge大规模视觉识别挑战赛)竞赛的第二名,解决ImageNet中的1000类图…

Padloc:一个直观的开源密码管理器

让我们了解一下这个具有令人愉悦的用户界面、跨平台可用的开源密码管理器。有大量适用于个人和团队的免费的和收费的密码管理器。然而,当谈到开源方案时,它通常仅限于几个好的方案,如 Seahorse、KeePassXC 和 Bitwarden。如果你已阅读过我们的…

【浅学Java】InnoDB存储引擎下MVCC(多版本并发控制 )

TOC 1. MVCC是什么 MVCC是面试中比较常见的一个问题,那么什么是MVCC机制,它的作用是什么? 它的英文全称是 Multi-Version Concurrency Control ,也就是“多版本并发控制”的意思。在MySQL InnoDB存储引擎下,RC、RR就…

DBeaver 超级详细的安装与使用

一、下载DBeaver DBeaver是一种通用数据库管理工具,适用于需要以专业方式使用数据的每个人;适用于开发人员,数据库管理员,分析师和所有需要使用数据库的人员的免费(DBeaver Community) 的多平台数据库工具。 DBeaver支持80多个数据…