synchronized锁升级全过程

1. 无锁状态

在 Java 对象头(Object Header)中,有一个 Mark Word,其中存储了对象的标志位和锁信息。初始状态下,对象处于无锁状态,此时 Mark Word 中包含对象的哈希码和一些标志位。

2. 偏向锁

为了减少轻量级锁的开销,Java 引入了偏向锁(Biased Locking)。当一个线程第一次访问同步代码块时,会将该对象的 Mark Word 设置为偏向该线程。这时,Mark Word 中存储的是该线程的 ID。

偏向锁的获取和撤销
  • 获取:如果一个线程访问一个未加锁且无其他线程竞争的同步块,对象将进入偏向锁状态,并将当前线程的 ID 写入 Mark Word。
  • 撤销:如果另一个线程尝试访问已偏向其他线程的对象,偏向锁会被撤销,进入轻量级锁状态。

3. 轻量级锁

轻量级锁(Lightweight Locking)在偏向锁竞争时被使用。轻量级锁使用 CAS(Compare-And-Swap)操作来尝试将对象的 Mark Word 替换为一个指向栈中锁记录的指针。

轻量级锁的获取和膨胀
  • 获取:当前线程在进入同步块时,会将对象的 Mark Word 复制到一个称为 Lock Record 的栈帧中,并尝试通过 CAS 操作将 Mark Word 指向 Lock Record。如果 CAS 成功,则表示获取锁成功;如果失败,则进入锁膨胀过程。
  • 膨胀:当 CAS 操作失败时,表示锁存在竞争,此时锁会膨胀为重量级锁。

4. 重量级锁

重量级锁(Heavyweight Locking)使用操作系统的互斥量(Mutex)实现。当锁膨胀为重量级锁时,对象的 Mark Word 会变为指向重量级锁的指针,线程在获取锁时可能会被阻塞。

重量级锁的获取和释放
  • 获取:当锁膨胀为重量级锁后,所有进入同步块的线程都会被操作系统阻塞,直到锁被释放。
  • 释放:当持有锁的线程退出同步块时,会释放重量级锁,并唤醒阻塞的线程。

5. 总结

锁的升级过程可以总结为以下几个步骤:

  1. 无锁状态:对象初始状态,无锁。
  2. 偏向锁:用于无竞争的场景,优化单线程访问。
  3. 轻量级锁:用于低竞争的场景,通过 CAS 操作进行锁竞争。
  4. 重量级锁:用于高竞争的场景,当轻量级锁的 CAS 操作失败时升级为重量级锁,使用操作系统的互斥量来管理线程竞争。

这种锁升级机制通过减少锁竞争时的开销,提高了 Java 程序的并发性能。然而,在高竞争的环境下,锁升级仍然可能带来显著的性能影响,因此需要根据实际情况进行优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值