【Java多线程进阶】synchronized工作原理
前言
本期讲解 synchronized 工作的原理以及常见的锁优化机制,相信大家在看完这篇博文后对 synchronized 工作流程有一定的理解。话不多说,让我们快速进入学习吧~
目录
1. 锁的工作流程
2. 偏向锁
3. 轻量级锁和重量级锁
3.1 轻量级锁
3.2 重量级锁
4. 常见的锁优化
4.1 锁消除
4.2 锁粗化
1. 锁的工作流程
众所周知,synchronized 关键字是用来加锁的,加锁的原因就是多个线程抢占资源导致线程执行的过程不具备原子性。
JVM 将 synchronized 加锁的过程分为四个状态分为无锁、偏向锁、轻量级锁、重量级锁。刚开始是无锁状态,加上锁后处于偏向锁状态,锁有了竞争锁升级为轻量级锁,锁的竞争更加激烈了升级为重量级锁状态。
举例说明:
有个女孩叫如花,有个男孩叫阿三,如花是个漂亮的女孩,阿三是个帅气又有钱的男孩。
阿三追求如花,如花不想确定情侣关系也不想放弃阿三,于是如花吊着阿三,此时就处于一个偏向锁状态。阿三就像锁,锁的竞争不激烈,如花有恃无恐,锁处于 偏向锁 状态。
某一天,如花发现阿三正在被其他女孩追求,如花慌了立马跟张三确定男女关系,此时就处于轻量级锁状态。锁的竞争激烈了,锁升级为 轻量级锁。
随着日子一天天过去,越来越多女孩开始爱慕阿三。如花更加紧张了,生怕张三离开她,于是越来越限制张三的自由了,此时就处于重量级锁状态。锁的竞争更加激烈了,锁升级为 轻量级锁。
在上述例子中,阿三为锁,如花为 JVM。JVM 通过锁的竞争程度,来决定锁的策略是什么。
2. 偏向锁
第一尝试获取锁的线程,优先处于偏向锁的状态。此时这个线程并未进行加锁操作,而是通过一个 标记 来确定这是第一次获取锁的线程。
如果代码在整个运行过程中,没有遇到其他线程来竞争锁。就不会进行加锁了。但,如果有线程进行竞争锁,此时偏向锁就会变成一把真正的锁(轻量级锁)。
偏向锁,主要体现能不加锁就不加锁这个概念,它实际上并没有加锁只是通过一个标记来确定锁于无竞争状态,等到锁有竞争情况发生了,偏向锁才会变成一把锁(轻量级锁)。
举例:
21世纪流行着这样一段关系:
有一个男孩小强和一个女孩小美,小强是一把锁,小美是一个线程。小强和小美想过着夫妻一般的生活但不去领证。此时,小美在使用这把锁的时候锁的状态为偏向锁,因为没有其他线程竞争这把锁。
某一天,小强在公司认识了一个女孩小宣,小宣是一个线程。小宣爱慕小强,于是追求他。小美不想小强被抢走,于是和小强结婚(领证)。此时,小美使用小强这把锁就变成了轻量级锁状态。最后小强只得对小宣说:“你是个好女孩,我配不上你”。
3. 轻量级锁和重量级锁
轻量级锁为了避免进入同步状态,采用了一些基于CAS操作的优化手段,但如果线程CAS操作失败并达到一定次数后,会进入自旋锁状态等待获取锁。但如果自旋等待的时间过长,就需要升级为重量级锁,这是为了让其它线程有机会抢到锁。
升级为重量级锁后,会将当前线程阻塞并进入内核态,而不再直接进入自旋锁状态等待,这样可以避免浪费CPU资源。同时,重量级锁在释放锁的时候,也需要进行内核态的操作,因此其释放锁的代价相对较高。
关于CAS相关信息在这篇博文中有详细介绍:【Java多线程进阶】CAS机制_一只爱打拳的程序猿的博客-CSDN博客
3.1 轻量级锁
通过上文讲解,我们了解到随着其他线程竞争锁,锁由偏向锁状态升级为轻量级锁状态。轻量级锁状态,实际上就是自适应的自旋锁状态。
此处的轻量级锁,是通过 CAS 机制来实现的:
- 通过 CAS 机制检查并且更新一块内存。
- 如果更新成功,则加锁成功。
- 更新失败,则认为锁被占用,继续自旋式的等待。
自旋式,就是通过一个循环来判定锁是否被占用。如果锁被占用此时会无限循环,直到锁不被占用退出循环。在此期间,自选锁一直占用着 CPU 资源,比较浪费。
3.2 重量级锁
如果锁竞争愈发激烈,自旋锁不能快速获取到锁的状态,就会升级为重量级锁。此时的重量级锁会引申到内核态与用户态。
轻量级锁与重量级锁在这篇文章中有详细介绍:【Java多线程进阶】常见的锁策略_一只爱打拳的程序猿的博客-CSDN博客
4. 常见的锁优化
常见的锁优化有两种:锁消除于锁粗化。请看下方讲解。
4.1 锁消除
锁消除是一种编译器优化机制,当代码块被 synchronized 锁住时。如果该代码块只被某一线程独占则 synchronized 就被编译器消除了,因为编译器会检查并认为该代码块并不需要加锁,也就是我们所说的锁被消除了。
当然,多个线程使用多把锁时,只要互不干扰各自使用各自的锁资源,这种情况锁也会被消除。
锁消除是一种优化技术,它可以减少不必要的锁操作对性能的影响,提高程序的执行效率,节省系统消耗的资源。
4.2 锁粗化
谈到锁粗化,我们会联想到一个“粒度感”,代码越多粒度越粗,代码越少粒度越细。在写代码的过程中,我们很难兼容到要保证代码少又要保证代码好。
比如在某个场景下,我们频繁的使用 加锁/解锁 操作,编译器会通过优化手段将这些频繁的 加锁解锁 进行粗化,这样就能大大减小系统开销,也就是我们所说的锁粗化。
举例说明:
在公司上班,老板上午安排了一个任务给我,下午安排了个任务给我,晚上又安排了一个任务给我,要求我明天晚上之前要完成。
如果我今天下午完成第一个任务打电话给老板并汇报工作,明天上午完成了第二个任务再打电话给老板,明天晚上完成了第三个任务又打电话给老板。
老板心里肯定想,这人烦不烦一起给我不就得了。(当然,在任务不紧急的情况下)
如果我一次性汇报三个任务,此时就大大减少了老板接电话(上锁)挂电话(解锁)的开销。
synchronized工作原理是什么?
synchronized 刚开始是无锁的状态,当 synchronized 所修饰的资源被线程独占后就升级为偏向锁状态,当 synchronized 被多个线程竞争后就升级为轻量级锁,锁的竞争越来越激烈并且锁释放得很慢此时就会升级为重量级锁状态。
什么是偏向锁、轻量级锁、重量级锁?
偏向锁:第一个使用到锁的线程,此时并未进行锁操作,编译器会使用一个标识来确定这个锁只被一个线程使用。
轻量级锁:当锁被多个线程竞争了,此时锁会从偏向锁升级为轻量级锁,轻量级锁会通过 CAS 机制即自旋操作,来无限循环尝试获取锁直到获取到锁为止。因此,在获取到锁之前会一直占用CPU资源,容易浪费资源。
重量级锁:当锁竞争激烈并且锁资源释放过慢,此时锁会中轻量级锁升级为重量级锁,重量级锁会跟随系统的调度不再进行自旋等待,直到锁释放了,再参与锁的竞争,大大减少了系统资源的浪费。
🧑💻作者:一只爱打拳的程序猿,Java领域新星创作者,CSDN、阿里云社区优质创作者。
📒博客主页:这是博主的主页
🗃️文章收录于:Java多线程编程
🗂️JavaSE的学习:JavaSE
🗂️Java数据结构:数据结构与算法
本篇博文到这里就结束了,感谢点赞,评论,收藏,关注~
相关文章:

【Java多线程进阶】synchronized工作原理
前言 本期讲解 synchronized 工作的原理以及常见的锁优化机制,相信大家在看完这篇博文后对 synchronized 工作流程有一定的理解。话不多说,让我们快速进入学习吧~ 目录 1. 锁的工作流程 2. 偏向锁 3. 轻量级锁和重量级锁 3.1 轻量级锁 3.2 重量级锁…...

C语言经典题目(三)
C站的小伙伴们,大家好呀!😊😊✨✨这一篇是C语言之经典题目篇,除程序设计,还有一些不错的程序分析,快来和我一起进入C语言的世界吧!✨✨✨ 💕C语言其他刷题篇在这里哦&…...

九、(补充文章四)Arcgis实现深度学习训练样本数据的批量制作——只靠原图+shp如何批量制作样本图片
之前写了一些个深度学习系列文 其中先是单张样本的制作方法 最后通过构造模型批量处理 大大提高了生成样本的速度 四、Arcgis实现深度学习河流训练样本数据的制作(使用软件批量获取样本图片)——对已经获取到的完整面状样本数据进行处理 但是这个方法不仅仅需要shp和原图 还需要…...

MKS SERVO4257D 闭环步进电机_系列8 CAN通讯示例
第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&a…...

UnityVR--组件9--视频组件VideoPlayer
目录 前言 参数解释 RenderMode渲染方式 VideoPlayer类中的API 前言 在之前的VR场景中已经使用过VideoPlayer播放视频(Unity.UI的交互(6)-播放视频),不过在VR中设置是有些不同的,这里更详细地说明一下V…...
Java 深拷贝和浅拷贝
Java 中的深拷贝和浅拷贝是针对对象复制而言的。 浅拷贝(Shallow Copy) 当对象进行浅拷贝时,只会复制对象本身和其中的基本数据类型属性,而不会复制引用对象的实际内容。具体而言,浅拷贝只会创建一个新的对象&#x…...
[ruby on rails] docker
docker安装 ubuntu14.04后自带docker安装包,可以直接安装 sudo apt-get updatesudo apt-get install -y docker.io# 安装后启动sudo service docker start查看docker信息 docker infodocker命令 sudo service docker start sudo service docker stop sudo servic…...

网络协议——STP协议是什么?是如何实现的?
作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、STP协议是什么 二、为什么需要STP协议 三、STP的实现过程 编辑 1、选举跟桥 2、给非跟桥交换机选举跟端口 3、给每个网段选…...

【C++】智能指针 学习总结 |std::shared_ptr |std::unique_ptr | std::weak_ptr
文章目录 前言一、智能指针介绍二、普通指针和智能指针的比较案例三、std::shared_ptr四、std::unique_ptr五、std::weak_ptr六、std::shared_ptr |std::unique_ptr | std::weak_ptr三大智能指针的区别 前言 参考答案:chatgpt 一、智能指针介绍 智能指针是C的一种…...
iptables防火墙
文章目录 一.linux防火墙基础1.linux 包过滤防火墙概述1.1netfilter1.2 iptables 2.包过滤的工作层次2.1 通信的五元素和四元素 3.iptables 的表、链结构3.1 规则链3.2 默认包括5种规则链3.3 规则表3.4 默认包括4个规则表 二.数据包过滤的匹配流程1.规则表之间的顺序2.规则链之…...

properties、yaml作为配置文件的特点
说明:在软件开发中,经常需要把一些配置写在文件中,如数据库配置、MyBatis配置等。这样,后续如果数据库参数有改动,就可以避免直接对代码做修改,只要修改配置文件中关于数据库的配置。关于配置文件的选择&am…...

JavaSE-03 【流程控制语句】
文章目录 JavaSE-03 【流程控制语句】第一章 流程控制1.1 流程概述1.2 顺序结构 第二章 判断语句2.1 判断语句---if2.2 判断语句---if...else2.3 判断语句---if...else if ... else 第三章 选择语句3.1 选择语句--switch3.2 case的穿透性 第四章 循环语句4.1 循环概述4.2 循环语…...

笔记本电脑的BIOS是怎么保护安全的?
随着攻防技术的不断演进,像BIOS攻击、高级网络代码攻击等手段层出不穷,“受害者”也不仅限于企业级服务器、存储,很多魔爪也开始伸向了拥有商业机密数据的PC。 BIOS是Basic Input/Output System(基本输入/输出系统)的…...

Xubuntu之将rm删除内容移至回收站(一百七十七)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

STM32F407实现1588v2(ptpd)
硬件: STM32F407ZGT6开发板 软件: VSCode arm-none-eabi-gcc openOCD st-link 在github搜到一个在NUCLEO-F429ZI开发板上移植ptpd的example,因为和F407差别很小,所以就打算用这个demo移植到手头的开发板上。因为目前只需要…...
架构师如何找到自己的商业模式
作为一个架构师,必须要在有限的资源下最大化架构活动所带来的商业价值。对于任何一个架构活动而言,架构师的可用资源,包括商业成本、研发成本、时间成本、迁移成本等等,都是非常有限的。但架构活动就是要在这些限制条件之下&#…...

SQLServer2022安装(Windows),已验证
一、SQLServer2022下载 1、官网下载地址 SQL Server 下载 | Microsoft 2、下载安装包 2.1、选择Developer版本,立即下载。 2.2、打开下载文件夹,双击运行SQL2022-SSEI-Dev.exe 尝试运行SQL2022-SSEI-Dev.exe,会收到以下信息:“…...

facenet, dlib人脸识别,人体检测,云数据库mysql,QQ邮箱,手机验证码,语音播报
目录 部分代码展示: 录入部分 识别部分编辑 活体检测部分编辑 同步到云数据库MySQL 其他操作 部分图片展示: 完整代码加ui链接: 涉及到的一些知识点的文章 部分代码展示: 录入部分 识别部分 活体检测部分 同步到云数…...
Spring Boot 面试题——定时任务
目录 1.什么是 cron 表达式?如何使用?2.Scheduled 注解有什么作用?3.介绍一下 spring-boot-starter-quartz。4.在 Spring Boot 中如何实现定时任务?4.1.使用 Schedule 注解4.2.Quartz 框架 1.什么是 cron 表达式?如何使…...

总建面64万平,配3所幼儿园+54班九年制学校,坪山江岭竹元规划
近日,坪山区城市更新和土地整备局发布,关于《坪山区马峦街道江岭竹元片区城市更新单元规划》已通过深圳市城市规划委员会法定图则委员会审批。现予以公告。 项目位于坪山区马峦街道,南邻南坪快速路,北邻比亚迪路,东西两…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...