在 Java 中,synchronized
关键字是用于实现线程同步的机制,它的锁膨胀升级过程指的是在多线程竞争情况下,锁的状态可能从无锁(偏向锁)逐渐升级为轻量级锁,再升级为重量级锁。
-
偏向锁(Bias Locking):在对象刚被创建时,它的内置锁是没有任何竞争的,这时 JVM 可以将锁偏向于第一个获取它的线程。这种情况下,锁被认为是"无竞争的",它会记录下获取锁的线程 ID,并且在后续的获取操作中,只要线程 ID 不变,就无需做任何同步操作,直接获取锁。偏向锁的目标是减少无竞争情况下的同步开销。如果有其他线程尝试竞争这个锁,偏向锁就会失效。
-
轻量级锁(Lightweight Locking):如果多个线程尝试获取同一个对象的锁,偏向锁就会失效,锁就会升级为轻量级锁。在轻量级锁的状态下,获取锁的线程会在自己的线程栈中分配一块空间,用于存储对象的原始数据(比如对象头信息),然后将对象头信息中的锁标志指向这块空间。当线程释放锁时,会将原始数据复制回对象头信息中,并尝试撤销轻量级锁状态。轻量级锁适用于短时间的竞争情况,减少了线程之间的互相切换。
-
重量级锁(Heavyweight Locking):如果轻量级锁的升级过程失败,即有更多线程竞争同一个锁,那么锁会升级为重量级锁。在重量级锁状态下,锁的竞争使用操作系统级别的互斥量实现。这种情况下,线程会进入阻塞状态,等待操作系统的调度,直到获取到锁资源才能继续执行。
锁的膨胀升级过程是动态的,具体的升级策略由 JVM 决定,根据竞争情况和线程执行的特性,JVM 会根据实际情况选择偏向锁、轻量级锁或重量级锁来进行同步。这样的设计使得 JVM 能够在不同的竞争情况下做出灵活的锁优化,以提高多线程程序的性能。