【Java并发实战】偏向锁-轻量级锁-重量级锁

Java synchronized锁机制深度解析:从JVM原理到高并发实战优化 在Java并发编程中,锁机制是保障线程安全的核心基础。其原理基于Java内存模型(JMM),通过互斥访问和内存可见性确保共享数据的一致性。从技术价值看,有效的锁策略能显著提升系统吞吐量,降低延迟,是构建高并发应用的基石。典型的应用场景包括电商秒杀、金融交易、实时数据处理等对数据一致性要求极高的领域。本文聚焦Java内置的synchronized关键字,深入剖析其底层实现如Mark Word与锁升级(偏向锁、轻量级锁、重量级锁),并结合高并发场景下的性能调优与死锁预防,帮助开发者掌握这一基础且强大的同步原语。 阅读详情

【Java并发实战】偏向锁-轻量级锁-重量级锁


在多线程并发编程中,synchronized一直都是元老级的角色,人们通常称为重量级锁,但是在jdk1.6之后,jdk就对synchronized做了大量的优化,这是候,我们就不能称他为重量级锁了,有时候它可以是很轻的。
synchronized
回顾一下synchronized
1.同步普通方法

public synchronized void  sync1() {
    // do somethings
}

在该方法中,synchronized锁的是当前实例的对象
2.同步静态方法

public static synchronized void sync2() {
    // do somethings
}

由于该方法是一个静态方法,那么它锁的是当前类的class对象。
3.通过方法块

public void sync3() {
    synchronized(this) {
        // do somethings
    }
}

public void sync4() {
    synchronized(MyTest.css) {
        // do somethings
    }
}

同步方法块是需要根据方法中具体同步的对象来实现的。

在上面代码中其实sync3()跟同步普通方法一样,锁的是当前实例对象;那么sync4方法就与同步静态方法一样,锁的是当前类的class对象。

从上面代码可以看出来的,我们通过使用synchronized关键字可以很简单的解决并发问题,但是其实是jvm底层通过使用一种叫内置锁的手段,简化了开发人员实现并发的复杂度,在jdk1.6以前 synchronized是基于重量锁实现的,即每次遇到同步代码都要获取锁,然后释放锁,在jdk1.6之后对其优化,根据不同场景使用不同的策略,这也就是 偏向锁、轻量锁、重量锁的来由。在介绍他们之前我先介绍一下另一个锁-自旋锁。听到这么多锁,是不是头晕,当初我学习的时候也是这样的。但是当你慢慢学习深入,你就会很容易的理解每个锁的作用

自旋锁

自旋锁顾明思意就是旋转等待的意思,那么它的作用是什么呢?
1.当前线程尝试去竞争锁
2.竞争失败,准备阻塞自己
3.但是并没有阻塞自己,而是采用自旋锁,进入自旋状态。
4.进入自旋状态,并且重新不断竞争锁。
5.如果自旋期间成功获取锁,那么结束自旋状态,否则进入阻塞状态。

如果在自旋期间成功获取锁,那么就减少一次线程的切换。

根据上面的解释我们可以很容易理解自旋锁的意义,因为CPU从内核状态切换至用户状态,线程的阻塞与恢复都会浪费资源的,但是通过自旋而不是去阻塞当前线程,那么就会节省这一个CPU状态的切换。

所以自旋锁适合在持有锁时间长,并且竞争不激烈的场景下使用。

使用-XX:-UseSpinning参数关闭自旋锁优化;-XX:preBlockSpin参数修改默认的自旋次数。

偏向锁

在实际场景中,如果一个同步方法,没有多线程竞争,并且总是由同一个线程多次获取锁,在这种场景下,如果每次还有阻塞线程,唤醒cpu从用户状态转核心态,那么对于cpu是一种资源的浪费,为了解决这类问题,就引入了偏向锁的概念。

“偏向”的意思是,偏向锁假设将来只有第一个申请锁的线程会使用锁(不会有任何线程再来申请锁),因此,只需要在Mark word中CAS记录owner(本质上也是更新,但初始值为空),如果记录成功,则偏向锁获取成功,记录锁的状态为偏向锁;否则说明有其他线程竞争,膨胀为轻量级锁。

具体的步骤如下:
1.访问同步代码块
2.检查对象头是都owner是否存储当前线程的id
3.如果没有,进行CAS尝试替换mark word中的owner。如果有执行同步代码块(代表获取锁成功)
4.修改成功(代表无竞争)owner修改为当前线程的id,执行同步代码块。修改失败(代表有竞争)进入撤销偏向锁,暂停线程并将owner置空,进入轻量级锁。
在这里插入图片描述
偏向锁无法使用自旋锁,因为一旦有其他线程申请资源,就破坏了偏向锁的假定。

如果你确定应用程序中所有的锁通常是在竞争状态,你可以通过JVM参数关闭偏向锁
UseBiasedLocking = false,那么程序会默认进入轻量锁状态。

轻量锁

偏向锁是为了解决同步代码在单线程下访问性能问题。
轻量级锁是为了解决减少无实际竞争情况下,使用重量级锁产生的性能消耗。

轻量锁,顾名思义,轻量是相对于重量的来说的,使用轻量级锁时,不需要申请互斥量(mutex),而是将mark word中的信息复制到当前线程的栈中,然后通过CAS尝试修改mrak word并替换成轻量锁,如果替换成功则执行同步代码块。如果此时有线程2来竞争,并且他也尝试cas修改mark word但是失败了,那么线程2进入自旋状态,如果在自旋状态也没有修改成功,那么轻量锁将膨胀成重量级锁,mark word会被修改成重量锁标记(10,),线程进入阻塞状态。

当然,由于轻量级锁天然瞄准不存在锁竞争的场景,及时存在锁竞争但是也不激烈,仍然可以通过使用自旋锁优化,自旋失败之后再膨胀称为重量级锁。

重量锁

在JVM规范中,synchronized是基于监视器锁(monitor)来实现的,它会在同步代码之前添加一个monitorenter指令,同时在同步代码结束处和异常处添加一个monitorexit指令去释放该对象的monitor。需要注意的是每一个对象都有一个monitor与之配对,当一个monitor被获取之后,也就是被monitorenter,它会处于锁定状态,其他尝试获取该对象的monitor线程会获取失败,只有当获取该对象的monitor的线程执行了monitorexit指令后,其他线程才有可能获取该对象的monitor成功。

所以从上面描述可以得出,监视器锁就是monitor它是互斥的(mutex)。由于它是互斥的,那么它的操作成本就非常的高,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。因此,后来称这种锁为“重量级锁”。

小结

偏向锁、轻量级锁、重量级锁适用于不同的并发场景:

偏向锁:无实际竞争,且将来只有第一个申请锁的线程会使用锁。
轻量级锁:无实际竞争,多个线程交替使用锁;允许短时间的锁竞争。
重量级锁:有实际竞争,且锁竞争时间长。

另外,如果锁竞争时间短,可以使用自旋锁进一步优化轻量级锁、重量级锁的性能,减少线程切换。
如果锁竞争程度逐渐提高(缓慢),那么从偏向锁逐步膨胀到重量锁,能够提高系统的整体性能。
同时需要注意锁可以升级,但是不能降级。
另外通过这次学习,大家应该也知道自从jdk1.6以后 synchronized已经被优化了,性能不会比Lock差
所以jdk.16版本及其以后版本的同学可以放心大胆的使用了。
最后附一张从偏向锁膨胀至重量锁的完全的流程图
在这里插入图片描述

Java中的偏向锁,轻量级锁, 重量级锁解析 参考文章 聊聊并发(二)Java SE1.6中的Synchronized Lock Lock Lock: Enter! 5 Things You Didn’t Know About Synchronization in Java and Scala Synchronization and Object Locking Java 中的锁 在 Java 中主要2种加锁机制: synchr... 阅读详情

相关推荐

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

超千万千万

会写Bug的攻城狮 2658

【Java并发编程】偏向锁/轻量级锁/重量级锁详解

深入解析了 Java 并发编程中的三种锁机制:偏向锁、轻量级锁和重量级锁。文章首先介绍了锁升级模型,然后详细解释了每种锁的工作原理、加锁和解锁过程,以及它们之间的转换条件。最后,文章分析了重量级锁的实现细节,包括 Monitor 的结构和操作过程。

叉烧钵钵鸡的博客 3133

基于CPCC_S_TASK_LIST_MAINTAIN的工艺路线组件批量分配实战与避坑指南

本文详细解析了SAP PP模块中基于CPCC_S_TASK_LIST_MAINTAIN函数实现工艺路线组件批量分配的实战技巧与避坑指南。针对批量分配的核心挑战,提供了参数配置、BAPI协同使用、Excel导入等解决方案,并分享了大容量数据处理优化经验,帮助用户高效完成工艺路线组件分配任务。

weixin_33563728的博客 306

Java中的偏斜锁,轻量级锁,重量级锁的简单理解

Java中的偏斜锁,轻量级锁,重量级锁的简单理解

Qcheung的博客 327

Field _II 仿真 学习笔记

参考Field II的使用说明,进行了四个例子的练习。仿真程序和结果如下: PURPOSE1:Calculate the received response from all elements of a linear array and plot the responses and the summed response 【计算来自所有线性阵元的接收响应,并绘制该响应以及叠加响应。】 >>

qq_34018578的博客 1万+

RK3568嵌入式Linux多屏显示开发指南

摘要:本篇RK3568嵌入式Linux多屏显示开发指南详细介绍了基于Qt应用层的实现方案。文章首先概述了技术架构,说明从Qt应用到硬件显示的完整流程。然后提供了两种实现方案:推荐使用Qt内置多屏支持方案,包含完整的C++代码示例和配置文件说明;对于需要精细控制的场景,给出了基于libdrm API的底层实现方案。最后重点讨论了屏幕旋转处理和多屏协同工作模式的关键技术要点,包括扩展桌面、镜像模式等实现方法。

froxy的专栏 1572

java中的锁——偏向锁,轻量级锁,重量级锁

否则测试Mark Word中偏向锁的标识符是否为1(当前是否为偏向锁,1是0否),如果不是偏向锁则使用CAS竞争锁(使用CAS将对象头的偏向锁指向当前线程),如果是则尝试使用CAS将对象头的偏向锁指向当前线程。偏向锁的撤销,需要等待全局安全点(在这个时间点上没有字节码正在执行),它会首先暂停拥有偏向锁的线程,检查持有偏向锁的线程是否处于活动状态(同步代码块是否执行完),不处于活动状态则将对象头设置为无锁状态,线程可以使用CAS竞争锁。),那么该线程会自动获取锁,降低获取锁的代价。

A_BCDEF_的博客 2130

bevformer详解(3): 逐行代码讲解

在这篇文章中,我们将从BEVFormer算法代码入手,深入探究BEV转换的流程。BEVFormer是一种基于Transformer的BEV转换模型,其核心思想是利用自注意力机制和交叉注意力机制,从,并通过Object Query与BEV特征的交互,完成3D目标检测和地图分割等任务。https://developer.baidu.com/article/details/3224715bevformer的网络结构由三部分组成, 模型结构所示,其中的是部分,对于的是的结构,对于部分,沿用的中的decoder部分,

@bangbang的博客 3701

Java synchronized偏向锁、轻量级锁、重量级锁

当创建对象时该对象的对象头状态会变成偏向锁状态(即使不加synchronized也是默认偏向锁状态),即Biased状态。thread指向偏向的线程,当有线程再次获取锁时,会判断是否为偏向的线程,如果是就可以直接执行同步代码块的内容。若不是,偏向锁升级为轻量级锁。 轻量级锁和偏向锁加锁方式一样,当偏向锁被其它线程获取时(未发生竞争),会自动升级为轻量级锁。 每个线程的栈帧都会包含一个锁记录,内部可以存储锁对象的Mar

m0_63463465的博客 2707

69、SAP数据库归档重做日志备份策略与工具详解

本文详细解析了SAP数据库归档重做日志备份的重要性及策略,介绍了SAP提供的备份工具brarchive及其配置和使用方法,探讨了BRBACKUP与BRARCHIVE的联合运行、一致在线备份、备用数据库备份场景以及备份策略的综合应用与优化。此外,还分析了备份过程中常见问题的解决方法、备份监控与评估流程、与第三方备份解决方案的集成方式,以及未来备份技术的发展趋势和应对策略。通过合理运用这些策略和工具,可以有效保障SAP数据库的安全性和可恢复性。

peace的博客 135

基于Simulink的永磁同步电机三闭环(位置/速度/电流)伺服仿真

本文详细介绍了基于Simulink的永磁同步电机三闭环伺服控制系统的设计与实现,针对机器人关节控制场景。系统采用位置环(外环)、速度环(中环)和电流环(内环)的嵌套结构,通过精确的带宽匹配(电流环1kHz、速度环200Hz、位置环20Hz)实现亚微米级位置跟踪。文中提供了完整的Simulink建模步骤,包括主电路搭建、三环PI控制器实现及坐标变换模块,并验证了系统性能:阶跃响应时间35ms,位置误差<0.05°,正弦跟踪误差<0.15°,负载突加恢复时间0.08s。最后提出了参数自适应整定、前馈

amy_mhd的博客 279

深入理解Java中的偏向锁、轻量级锁与重量级锁

偏向锁:适用于锁主要被一个线程持有的场景,减少了锁的获取与释放开销。轻量级锁:适用于锁被少量线程竞争的场景,通过CAS操作实现快速的锁获取。重量级锁:适用于锁被高频率、多线程竞争的场景,确保锁的独占性。通过合理理解和应用这些锁机制,结合良好的并发编程实践,可以显著提升Java应用程序的性能和响应性。同时,随着Java版本的不断演进,锁的优化机制也在持续改进,开发者应及时关注最新的JVM优化技术,以充分利用其带来的性能优势。

qq_42798343的博客 1890

计算机视觉教程1-1:透视空间与透视变换

在生活中,透视现象很常见,其物理本质是光的直线传播。由于人眼与相机在捕获图像时均存在透视现象,因此计算机几何基于透视空间进行研究。本节介绍透视变换原理

FRIGIDWINTER的博客 3091

最全【Java并发实战】偏向锁-轻量级锁-重量级锁,阿里内部爆款架构师Kafka源码笔记开源

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,也祝愿大家都能够升职加薪!本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取。

2401_84584628的博客 636

3、流程引擎下载安装与部署

camunda有多种使用方式,此处先使用独立平台的方式部署引擎,这种用法适合分布式,微服务化,多语言异构系统的使用方式。

leyoliu的博客 5520

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java锁升级机制深度解析:从偏向锁到重量级锁的完整演进之路

Java的锁升级机制是JVM并发优化艺术的杰出体现。它通过四级锁状态的无缝切换,在安全与性能之间找到了精妙的平衡点。理解这一机制不仅有助于编写高性能的并发代码,更能让我们深入理解JVM的设计哲学。从无锁到重量级锁的每一步升级,都是对当前竞争状况的智能响应。虽然偏向锁在现代JDK中逐渐淡出,但锁升级的核心思想——根据实际情况动态调整同步策略——依然是我们设计并发系统时需要遵循的重要原则。

用文字记录技术,用分享回馈社区,用坚持见证成长 1222

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

锁升级原理

Java 中的锁升级(Lock Escalation)是 关键字实现高效并发控制的核心机制。其本质是通过 对象头的 Mark Word 动态调整锁的粒度,从无锁状态逐步升级到重量级锁,以平衡性能与线程安全。以下是 Java 锁升级的详细原理和实现细节:每个 Java 对象在内存中分为三部分:Mark Word 是对象头中的关键部分(64 位 JVM 中占 64 位),记录了锁状态和标志位:Java 锁升级从低开销到高开销分为四个阶段,逐步适应竞争强度:Java 的锁升级是单向的: 使用工具分析锁竞争:

m0_61600773的博客 592

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

java synchronized 锁优化:偏向锁、轻量级锁、重量级锁升级流程

快速回顾:① synchronized 锁会按 “偏向锁→轻量级锁→重量级锁” 按需升级;② 锁优化核心是 “细粒度、短持有、低竞争”;③ 需结合 Java 版本选择锁策略,避免版本适配问题。延伸学习:① JVM 锁优化的底层实现(对象头、监视器锁);② 并发工具(ConcurrentHashMap、原子类)的锁优化机制;③ 虚拟机参数对锁优化的影响。面试备准:1. Q:synchronized 的锁升级流程?A:单线程偏向锁→低竞争轻量级锁(自旋)→高竞争重量级锁(阻塞);2. Q:偏向锁的作用?

m0_67391377的博客 644

Java并发编程实战 Day 9:锁优化技术

掌握了偏向锁、轻量级锁和重量级锁的原理与应用场景。学会了通过JVM参数调优提升锁性能。理解了锁消除的实现机制。

在未来等你的专栏 792

深入Java并发:synchronized锁升级机制全解析

深入Java并发:synchronized锁升级机制全解析

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 892

Synchronized锁升级流程

Java中的synchronized关键字通过同步方法和代码块实现线程安全,底层基于对象监视器锁机制。在字节码层面表现为monitorenter和monitorexit指令,利用对象头的Mark Word记录锁状态。JDK 1.6后引入锁升级优化:从偏向锁(单线程场景)到轻量级锁(线程交替执行),最终升级为重量级锁(高竞争场景)。这种机制在保证线程安全的同时,显著提升了并发性能。

qq_53182263的博客 709

深入剖析Java并发编程中的锁优化与性能调优实战

Java并发编程中的锁优化是一个系统工程,需要开发者深入理解JVM的锁机制,并在应用层采取合理的编程策略。从偏向锁到无锁编程,从减小锁粒度到读写分离,每一种技术都有其适用的场景。最终的优化效果需要通过严谨的性能测试和监控来验证。记住,没有一劳永逸的银弹,最佳的锁策略永远是针对特定工作负载和系统特征而定制的。

currypop17的博客 888

深入拆解 synchronized:从偏向锁到重量级锁的升级之旅与优化秘籍

本文深入剖析Java中synchronized的底层实现:详解偏向锁、轻量级锁到重量级锁的升级机制,结合对象头Mark Word结构、JVM锁优化(自旋、消除、粗化、逃逸分析),并附死锁排查实战,助你真正掌握并发同步原理。

果酱 の 博客 436
下一篇: 深入理解Java类加载器(一):Java类加载原理解析续
给自己加加油
博客等级 码龄8年 302粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值