Java synchronized锁升级过程简述(面试可用)

本文详细介绍了Java锁的升级过程,从无锁到偏向锁、轻量级锁、锁自旋,直至最后的重量级锁。偏向锁适用于单线程场景,轻量级锁在多线程竞争时介入,锁自旋避免线程被阻塞,而当自旋失败则升级为重量级锁。理解这些机制有助于优化多线程程序的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java 锁升级流程

Synchronized 的锁升级流程是这样:无锁 ----> 偏向锁 ----> 轻量级锁----> 锁自旋 ----> 重量级锁

在这里插入图片描述

偏向锁

偏向锁,简单的讲,就是在锁对象的对象头中有个ThreaddId字段, 这个字段如果是空的,第一次获取锁的时候,就将自身的ThreadId写入到锁的ThreadId字内,将锁头内的是否偏向锁的状态位置1.这样下次获取锁的时候,直接检查ThreadId是否和自身线程Id一致,如果一致,则认为当前线程已经获取了锁,因此不需再次获取锁,略过了轻量级锁和重量级锁的加锁阶段。提高了效率。(摘抄的哈哈)

轻量级锁

轻量级锁,偏向锁是单线程下的锁优化,这个就说多线程下的锁优化了,当有多个 线程竞争同一个临界资源,这个时候偏向锁就会被撤(这个步骤也是十分消耗资源的),然后升级为轻量级锁,这个也是一个基于CAS的乐观锁。

锁自旋

锁自旋,什么是锁自旋呢,很简单就是线程自己做一些无用功,避免线程被挂起阻塞 ,它自己在哪里做一些空任务,然后去竞争锁,避免被挂起阻塞(阻塞和唤醒是又是十分消耗性能的行为,这边涉及到用户态和核心态的操作系统问题,一般我们操作的都是用户态,但是线程的挂起阻塞是需要从用户态切换到核心态,同样,线程唤醒也一样,这个步骤会造成巨大的性能消耗,能避免尽量避免)。当然,锁自旋也是会消耗一定的CPU的

重量级锁

重量级锁,也就是再一次的锁升级。这个时候线程就是进行锁自旋也不到锁,因为锁自旋也是需要消耗一定资源的,所以它不可能一直自旋自旋失败了,那么就进行锁膨胀,升级为重量级锁。

码字不易,给个赞咯
下面是我得公众号二维码,扫一扫可能有惊喜哦哈哈
在这里插入图片描述

### Javasynchronized关键字的升级机制原理 在Java中,`synchronized`关键字的升级机制是为了优化多线程环境下的性能。早期版本的`synchronized`是一个重量级(悲观),它依赖操作系统层面的互斥量(Mutex)来实现线程同步,这种实现方式会导致频繁的上下文切换,从而降低程序性能。为了解决这一问题,JVM对`synchronized`进行了优化,引入了升级机制,将分为**无**、**偏向**、**轻量级**和**重量级**四种状态。 #### 的状态及升级过程 1. **无状态** 当对象刚被创建时,其处于无状态,即没有任何线程持有该。此时,对象头的Mark Word中存储的是对象的元数据信息,例如哈希码或GC年龄等[^3]。 2. **偏向** 当第一个线程尝试访问一个处于无状态的对象时,JVM会将该对象的升级为偏向。具体来说,JVM会通过CAS操作将线程ID写入对象头的Mark Word中。如果CAS操作成功,则说明当前线程成功获取了偏向。此后,当同一个线程再次访问该对象时,无需进行额外的同步操作,只需检查Mark Word中的线程ID是否与当前线程匹配即可[^4]。 3. **轻量级** 如果有另一个线程尝试访问已经处于偏向状态的对象,且偏向无法撤销(例如偏向的时间窗口已过期或竞争过于频繁),那么会被升级为轻量级。在这种状态下,JVM会在当前线程的栈帧中创建一个名为“记录”的空间,并通过CAS操作将对象头的Mark Word复制到记录中。如果CAS操作成功,则说明当前线程成功获取了轻量级;否则,表示存在竞争,需要进一步升级为重量级[^2]。 4. **重量级** 当多个线程同时竞争同一个时,会被升级为重量级。此时,JVM会利用操作系统提供的互斥量(Mutex)来实现线程间的同步。所有未获取到的线程都会被挂起,直到被释放并唤醒它们。重量级的性能开销较大,但在高并发场景下是不可避免的选择[^3]。 #### 升级的目的 升级机制的核心目的是在不同的竞争强度下选择合适的实现方式,以减少不必要的性能开销。偏向适用于单线程访问的场景,可以避免同步操作;轻量级适用于低竞争场景,能够减少竞争带来的开销;而重量级则适用于高竞争场景,尽管性能较差但能保证线程安全[^3]。 #### 监控工具 为了分析的竞争情况和性能瓶颈,可以使用以下工具: - 使用`jstack <pid>`命令查看线程的状态,结合`grep -A 10 "java.lang.Thread.State"`过滤相关信息。 - 使用`jcmd <pid> JFR.start duration=60s filename=lock.jfr`记录事件,生成性能分析报告。 ```python # 示例代码:同步方法 public class SyncMethod { public int i; public synchronized void syncTask() { i++; } } ```
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memory_cood

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值