Synchronized的锁升级过程

在锁升级过程中,synchronized 锁的状态会从偏向锁、轻量级锁、重量级锁逐步升级,具体过程如下:

  1. 偏向锁(Biased Locking)

    • 初始状态下,锁对象的标记为无锁状态。
    • 当第一个线程进入同步块时,JVM会尝试将锁升级为偏向锁,并将该线程的ID记录在锁对象的头部。
    • 如果其他线程试图访问同步块,偏向锁会被撤销,升级为轻量级锁。当持有偏向锁的线程执行完同步代码块后,JVM 会尝试将偏向锁恢复为无锁状态,并清除锁对象中记录的线程ID。这是为了确保在没有其他线程访问同步代码块的情况下,能够尽早释放锁对象,以便其他线程能够尽快获取到锁。
  2. 轻量级锁(Lightweight Locking)

    • 当有第二个线程尝试获取同步块的锁时,偏向锁会被撤销,锁会升级为轻量级锁。
    • JVM 会将当前线程尝试获取锁的对象头部信息复制到当前线程的栈帧中,并尝试使用 CAS(Compare and Swap)操作将对象头部信息修改为指向当前线程锁记录的指针。
    • 如果 CAS 操作成功,则表示该线程成功获取了锁,继续执行同步代码块;否则,说明有其他线程也在竞争锁,轻量级锁会升级为重量级锁。
  3. 重量级锁(Heavyweight Locking)

    • 当轻量级锁竞争失败,或者锁对象的锁记录存在多个线程竞争时,锁会升级为重量级锁。
    • 重量级锁会导致竞争失败的线程进入阻塞状态,而不是忙等待,从而减少了竞争的消耗。

偏向锁通过对比Mark Word解决加锁问题,避免执行CAS操作。

轻量级锁是通过用CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒而影响性能。

重量级锁是将除了拥有锁的线程以外的线程都阻塞。

总的来说,synchronized 锁会根据竞争情况逐步升级为偏向锁、轻量级锁和重量级锁,从而保证了多线程环境下对共享资源的安全访问。

补充:

如何理解自旋

自旋是一种在等待某个条件满足时不释放 CPU 使用权的行为。在自旋过程中,线程会在原地循环等待,不停地检查条件是否满足,而不会进入阻塞状态或释放 CPU 使用权。因此,自旋会消耗 CPU 时间,但避免了线程进入和退出阻塞状态的开销,可以提高程序的响应速度和性能。

需要注意的是,自旋适用于等待时间较短、且预计条件很快就会满足的情况下。如果等待时间过长,自旋可能会导致 CPU 时间的浪费,影响系统的整体性能。因此,在使用自旋时需要谨慎考虑等待时间和自旋次数,以及合适的条件。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值