【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班九年制学校,坪山江岭竹元规划
近日,坪山区城市更新和土地整备局发布,关于《坪山区马峦街道江岭竹元片区城市更新单元规划》已通过深圳市城市规划委员会法定图则委员会审批。现予以公告。 项目位于坪山区马峦街道,南邻南坪快速路,北邻比亚迪路,东西两…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...