讲透synchronized锁膨胀的过程

  synchronized Java 中的一个关键字,用于实现同步。当多个线程同时访问一个共享资源时,为了避免出现竞态条件(race condition),需要对这些线程进行同步控制。在 Java 中,我们可以使用 synchronized 关键字来实现同步控制。

    当一个线程尝试获取一个已经被其他线程获取的 synchronized 锁时,该线程会进入锁膨胀(lock escalation)的过程。在锁膨胀的过程中,JVM 会尝试将轻量级锁(lightweight lock)升级为重量级锁(heavyweight lock),以提高同步控制的效率和可靠性。

具体来说,锁膨胀的过程如下:

  1. 初始状态:当一个线程尝试获取一个对象的锁时,如果该对象的锁状态为无锁状态(unlocked),则该线程会尝试使用 CAS 操作将该对象的锁状态设置为轻量级锁状态(lightweight locked)并将当前线程 ID 记录在对象头中。
  2. 轻量级锁:如果 CAS 操作成功,那么该线程就拥有了该对象的轻量级锁,并可以直接访问该对象。
  3. 自旋等待:如果 CAS 操作失败,那么表示该对象已经被其他线程获取了轻量级锁。此时,当前线程会进入自旋(spin)状态,使用自旋锁等待其他线程释放该对象的轻量级锁。
  4. 自旋锁优化:在自旋等待的过程中,JVM 还会进行一些优化,例如自适应自旋(adaptive spin),即根据上一次自旋等待的时间来决定下一次自旋等待的时间。这些优化可以提高同步控制的效率。
  5. 锁膨胀:如果自旋等待超过了一定的次数或时间,那么 JVM 就会将该对象的锁状态升级为重量级锁状态(heavyweight locked)。此时,当前线程会进入阻塞状态,并将自己加入到该对象的等待队列中,等待其他线程释放该对象的锁。重量级锁是基于操作系统的互斥量(mutex)实现的,因此会涉及到用户态和内核态之间的切换,开销较大。
  6. 锁降级:如果在阻塞等待的过程中发现该对象的锁状态可以降级为轻量级锁或无锁状态,那么 JVM 就会将该对象的锁状态降级,并唤醒等待队列中的线程。这样可以减少阻塞等待和用户态和内核态之间的切换开销。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值