synchronized锁机制升级过程——面试题

1. 无锁状态

  • 对象在没有被任何线程锁定时处于无锁状态。此时对象头中的锁标志位通常表示为无锁(例如,标记字段的特定位组合表示无锁或偏向锁状态)。

2. 偏向锁(Biased Locking)

  • 初次获取:当线程首次获得对象锁时,如果对象处于无锁状态,系统会将其升级为偏向锁。此时会在对象头的 MarkWord 中记录当前线程的 ID,表明该锁偏向于这个线程。后续该线程再次请求该锁时,只需验证 MarkWord 中的线程 ID 是否与当前线程 ID 相符,相符则无需进一步同步操作即可直接获取锁。
  • 撤销与偏向撤销:当有第二个线程尝试获取该偏向锁时,偏向锁将被撤销,恢复到无锁状态。随后,锁会根据竞争情况升级为轻量级锁或重量级锁。此外,为了应对程序运行过程中线程生命周期较短、偏向锁失效的情况,JVM 还会定期或在特定条件下进行全局偏向锁撤销操作。

3. 轻量级锁(Lightweight Locking)

  • 获取:当线程 A 在偏向锁撤销后尝试获取锁时,如果发现锁已被偏向线程 B 持有,线程 A 将尝试使用 CAS(Compare-and-Swap)操作将对象头的 MarkWord 替换为指向线程 A 线程栈中锁记录(Lock Record)的指针,并将锁记录中的指针回写到 MarkWord。如果 CAS 成功,线程 A 获得锁,否则说明有其他线程(可能是线程 B 或其他新竞争者)也在尝试获取锁,此时进入下一步。
  • 自旋与升级:若 CAS 失败,线程 A 会进入自旋状态,循环尝试获取锁。如果在一定次数(默认通常是10次)的自旋后仍未能获得锁,轻量级锁将升级为重量级锁。升级过程包括:线程 A 首先暂停自旋,然后在对象头中设置标志,触发锁膨胀,将锁变为重量级锁。同时,线程 A 会被挂起,加入到锁对象对应的 Monitor(重量级锁)的等待队列中。

4. 重量级锁(Heavyweight Locking)

  • 获取:一旦锁升级为重量级锁,所有后续尝试获取锁的线程都会被阻塞,放入操作系统层面的等待队列中,由操作系统进行线程调度和上下文切换。
  • 释放:持有锁的线程执行完同步代码块后,释放锁。操作系统会唤醒等待队列中的一个(或多个,取决于锁策略)线程,使其重新尝试获取锁。

无锁、偏向锁、轻量锁属于用户态(jvm),重量锁属于内核态(系统)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值