跳到主要内容

简述多线程中 synchronized 锁升级的原理?

参考答案:

在Java中,synchronized关键字用于控制多个线程对共享资源的访问。为了提高性能和效率,Java虚拟机(JVM)对synchronized的实现进行了优化,其中之一就是引入了锁升级机制。锁升级是一个逐步的过程,根据竞争情况动态地调整锁的类型,从而减少不必要的性能开销。

synchronized锁升级的原理主要包括以下三个步骤:

  1. 偏向锁(Biased Locking):在对象头中有一个threadid字段,当第一个线程访问同步代码块时,如果threadid为空,JVM会让当前线程持有偏向锁,并将threadid设置为该线程的ID。这样,当同一个线程再次访问同步代码块时,只需检查threadid是否与当前线程ID相同,相同则直接持有锁进入同步代码块,无需进行额外的同步操作。
  2. 轻量级锁(Lightweight Locking):如果多个线程尝试访问同步代码块,并且threadid与当前线程ID不同,JVM会升级锁为轻量级锁。在这个阶段,线程会自旋(忙等待)一定次数来尝试获取锁,而不是进入阻塞状态。如果其中一个线程获取到锁,它将进入临界区执行。自旋的次数和等待时间可以根据需要进行调整。
  3. 重量级锁(Heavyweight Locking):如果自旋超过一定次数或者有其他线程争夺锁,锁将进一步升级为重量级锁。在这个阶段,如果线程无法获取锁,它将进入阻塞状态,等待锁的释放。重量级锁是最耗费系统资源的锁状态,因为它涉及线程的上下文切换和内核态与用户态的切换。

通过锁升级机制,JVM可以根据竞争情况动态地调整锁的类型,从而提高性能和效率。在大多数情况下,偏向锁和轻量级锁能够满足需求,只有在高竞争情况下才会升级为重量级锁。这种机制有助于减少不必要的性能开销,提高多线程程序的执行效率。