Synchronized底层机制:偏向锁、轻量级锁与重量级锁及其锁升级过程

前言:

在Java并发编程中,synchronized关键字是用于实现线程同步的重要工具。在JVM中,synchronized的底层实现涉及到了偏向锁、轻量级锁和重量级锁这三种锁状态,以及锁升级过程。在之前的文章中介绍到过,这篇文章详细对锁升级进行说明。

在这里插入图片描述

偏向锁

偏向锁是Java 6中引入的一种优化手段,它的核心思想是:如果一个线程获得了锁,并且没有释放,那么下次当这个线程再次尝试获得这个锁的时候,不需要做任何同步操作,不需要进行CAS操作或者阻塞,可以直接获得这个锁。偏向锁主要是为了避免无竞争情况下的同步原语,进一步提高程序的运行性能。

如何获取偏向锁

当一个线程首次访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储偏向的线程ID。

在后续操作中,如果这个线程再次尝试获得这个锁,JVM只需检查对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果是,就表示线程已经获得了锁,可以继续执行同步代码块。

如何撤销偏向锁

当一个线程释放偏向锁时,JVM并不会立即清除对象头中的偏向线程ID,而是将其设置为一个特殊值,表示该锁已经被释放。这样,当其他线程尝试获取这个锁时,JVM会检测到这个特殊值,从而知道该锁已经被释放,可以重新进行偏向锁的获取操作。
在这里插入图片描述

轻量级锁

轻量级锁是为了减少获得锁和释放锁所带来的性能消耗而引入的。在锁竞争不激烈的情况下,轻量级锁可以提高程序的性能。它的实现主要依赖于自旋和CAS操作。

如何轻量级锁

当线程尝试获取一个被其他线程持有的轻量级锁时,它会进入自旋状态,尝试通过CAS操作获取锁。如果自旋等待超过预定的次数仍然没有成功获得锁,那么该线程将会被挂起,转换为重量级锁。在Java 6之后,对于非偏向锁的同步块,在第一次被访问时也会尝试使用轻量级锁。

如何轻量级锁

轻量级锁的释放过程相对简单。当持有锁的线程释放锁时,只需将对象头中的Mark Word设置为无锁状态即可。这样,其他线程就可以尝试获取这个轻量级锁了。

重量级锁

重量级锁是传统的同步锁实现方式,它在JVM中是通过对象监视器Monitor来实现的。当一个线程尝试获取一个被其他线程持有的重量级锁时,它会被阻塞并放入锁的等待队列中。

当持有锁的线程释放锁时,等待队列中的一个线程会被唤醒并获得锁。这种实现方式虽然保证了线程安全,但是在竞争激烈的情况下会导致大量的线程切换和上下文切换,从而带来较大的性能开销。

锁升级过程

接下来详细介绍一下锁升级的过程,这块也是面试中的重点!

在JVM中,synchronized的底层实现涉及到了偏向锁、轻量级锁和重量级锁这三种锁状态的转换过程,即锁升级过程。

当一个线程首次访问同步块并获得锁时,该锁的状态为偏向锁。

在后续的操作中,如果该线程再次尝试获得这个锁,JVM会检查该锁的状态并进行相应的处理。如果该锁的状态为偏向锁且偏向的线程ID与当前线程的ID相同,则表示该线程已经获得了锁,可以继续执行同步代码块;如果该锁的状态为偏向锁但偏向的线程ID与当前线程的ID不同,则表示该锁已经被其他线程持有,需要进行竞争。

此时,JVM会将该锁的状态升级为轻量级锁或重量级锁,具体取决于竞争的激烈程度。如果竞争不激烈,JVM会尝试使用CAS操作获取轻量级锁;如果竞争激烈或自旋等待超过预定的次数仍然没有成功获得轻量级锁,则将该锁的状态升级为重量级锁并阻塞当前线程放入等待队列中等待唤醒。

当持有锁的线程释放锁时也会根据当前锁的状态进行相应的处理。如果当前锁的状态为重量级则唤醒等待队列中的一个线程并获得锁;如果当前锁的状态为轻量级或偏向则只需将对象头中的Mark Word设置为无锁状态即可。

同时也祝愿各位小伙伴儿在面试的过程中这块知识点答得都对,看完全会!

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeeCode前端算法基础100题(3)- N皇后

一、问题详情: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后…

BLP9H10-30GZ LDMOS 功率晶体管 Ampleon

BLP9H10-30GZ 30W塑料LDMOS 功率晶体管,适用于频率范围为616 MH 至960 MHz的基站应用。 BLP9H10-30GZ 特点和优势: 高效率 出色的耐用性 专为宽带操作而设计 出色的热稳定性 高功率增益 集成ESD保护 有关 RoHS 合规性 BLP9H10-30GZ应用程序&…

网易区块链,网易区块链赋能赣州脐橙数字藏品,数字指纹解决方案

目录 网易区块链 网易区块链赋能赣州脐橙数字藏品,助力革命老区三农之路 数字指纹解决方案 网易区块链 网易区块链成立于2017年,致力于Web3.0区块链技术的研发和应用。自主研发的区块链“天玄”引擎,在单链场景下支持每秒最高30万笔交易,单日可处理上链数据超10亿。 与…

智慧工地解决方案,Spring Cloud智慧工地项目平台源码

智慧工地一体化信息管理平台源码,微服务架构JavaSpring Cloud UniApp MySql 智慧工地云平台是专为建筑施工领域所打造的一体化信息管理平台。通过大数据、云计算、人工智能、物联网和移动互联网等高科技技术手段,将施工区域各系统数据汇总,建…

Notepad++批量添加引号

工作中经常会遇到这样情景:业务给到一批订单号,需要查询这批订单的某些字段信息。在where条件中需要传入这些订单号的数组,并且订单号用引号引起,用引号隔开。 字符串之间长度相同 可以按住CtrlAlt和鼠标左键选中区域&#xff0…

Talk | UCSB博士生许闻达:细粒度可解释评估初探

本期为TechBeat人工智能社区第551期线上Talk。 北京时间11月29日(周三)20:00,UC Santa Barbara博士生—许闻达的Talk将准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “细粒度可解释评估初探”,分享了他们团队在具备解释性的细粒度…

界面组件DevExpress Reporting v23.1新版亮点 - UX功能增强

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v23.1已于前段时间…

python实现获取aws route53域名信息

最近由于工作原因接触到aws的服务,我需要实时获取所有的域名信息,用于对其进行扫描,因此写了一个自动化爬取脚本 给需要的人分享。 1.基础准备 代码环境:python3 第三方库:boto3 (安装方法pip install…

爬虫为什么都选择python语言?爬虫使用代理IP有什么优势?

首先,让我们了解一下为什么爬虫都选择Python语言。 1.语言简洁易学 Python语言的设计哲学是“优雅”、“明确”、“简单”。这使得Python成为一种易于阅读和编写的语言,即使是初学者也可以快速上手。 2. 丰富的库和工具 Python拥有众多的第三方库和工…

【Java 并发编程】进程线程、lock、设计模式、线程池...

博主:_LJaXi Or 東方幻想郷 专栏: Java | 从入门到入坟 Java 并发编程 并发编程多线程的入门类和接口线程组和线程优先级线程的状态及主要转化方法线程间的通信重排序和 happens-beforevolatilesynchronized 与锁CAS 与原子操作AQS计划任务Stream 并行计…

leetcode:循环队列

题目描述 题目链接:622. 设计循环队列 - 力扣(LeetCode) 题目分析 我们开辟空间的时候多开一个,k是队列的长度,我们开k1个空间,定义一个front指向头,back的下一个指向尾 当frontback的时候&am…

Ps:子路径的布尔运算

在“路径”面板的一个路径层上,若存在一个以上的路径时,我们称这些路径为“子路径”。 矢量工具(比如钢笔工具、形状工具以及路径选择工具等)的选项栏上的“路径操作” Path Operations弹出菜单中提供了有关子路径的布尔运算的选项。 尽管在弹…