interview
java-concurrency
当Java的synchronized升级到重量级锁时,会发生什么?

Java并发面试题, 当 Java 的 synchronized 升级到重量级锁时,会发生什么?

Java并发面试题, 当 Java 的 synchronized 升级到重量级锁时,会发生什么?

QA

Step 1

Q:: 当 Java 的 synchronized 升级到重量级锁时,会发生什么?

A:: 当 synchronized 升级到重量级锁时,JVM 会通过操作系统的原生互斥锁(Mutex)来进行线程同步。这意味着线程的阻塞和唤醒不再是由 JVM 自行控制,而是依赖于操作系统的内核调度。重量级锁会导致线程从用户态进入内核态,这个过程非常耗时,从而降低了系统的性能。这种锁通常是在锁竞争激烈时发生的,因为轻量级锁和偏向锁已经无法满足同步需求。

Step 2

Q:: 什么是 Java 的偏向锁?

A:: 偏向锁(Biased Locking)是 JVM 为了提高同步性能而引入的一种优化机制。当一个线程首次获得锁时,JVM 会将该锁的偏向标记设置为该线程。以后该线程再次进入同步块时,不再需要执行同步操作(如 CAS 操作),而是直接进入,从而减少了同步的开销。但如果有其他线程尝试获取锁时,偏向锁会撤销,锁会升级为轻量级锁。

Step 3

Q:: 轻量级锁和重量级锁的区别是什么?

A:: 轻量级锁(Lightweight Lock)使用 CAS 操作来尝试获取锁,它避免了重量级锁所需的操作系统调用。轻量级锁在锁竞争较少的情况下性能很好,但在高并发场景下会导致自旋消耗 CPU,从而影响性能。重量级锁则依赖于操作系统的锁机制,当锁竞争激烈时,线程会被挂起,直到锁被释放。重量级锁更适合在竞争非常激烈的情况下使用。

Step 4

Q:: 为什么 synchronized 会有锁升级的过程?

A:: synchronized 锁升级的目的是为了在不同的竞争场景下,动态调整锁的实现方式,以最大化性能。在没有竞争的情况下,使用偏向锁可以消除同步开销;在轻度竞争下,轻量级锁通过自旋避免线程阻塞;而在激烈竞争下,重量级锁通过挂起线程减少 CPU 消耗。这种分级机制让 synchronized 能够在不同的并发场景下都保持相对较高的性能。

用途

面试这个内容是因为在高并发环境下,锁的实现和性能优化是非常关键的。在实际生产环境中,如果对锁的理解不透彻,可能会导致系统性能瓶颈,甚至出现死锁等问题。了解锁的不同实现机制(如偏向锁、轻量级锁、重量级锁)及其适用场景,有助于开发者在面对并发问题时做出更好的设计决策,并有效地提升系统的并发性能。\n

相关问题

🦆
Java 中的 volatile 关键字是什么?

volatile 是一种轻量级的同步机制。它确保变量的更新操作对所有线程可见,即一个线程修改了变量的值,其他线程能够立即看到修改后的值。它还禁止指令重排序优化,从而避免了多线程环境下的可见性问题。volatile 适用于简单的状态标志或双重检查锁定单例模式。

🦆
什么是 CAS 操作?

CAS(Compare-And-Swap)是一种原子操作,用于实现无锁并发。它包含三个操作数:内存位置、期望值和新值。如果内存位置的当前值与期望值相等,那么将该位置更新为新值;否则不做任何操作。CAS 是轻量级锁的基础,可以避免传统锁的开销,但在高竞争下会导致自旋和性能下降。

🦆
什么是 Java 中的 ThreadLocal?

ThreadLocal 是 Java 中一种用于实现线程局部变量的机制。通过 ThreadLocal,您可以为每个线程分配独立的变量副本,这样每个线程都可以修改自己独立的副本,而不会影响其他线程。ThreadLocal 通常用于需要在多线程环境下共享变量但又不希望线程之间相互影响的场景,比如数据库连接、会话信息等。

🦆
Java 中的 ReentrantLock 和 synchronized 的区别是什么?

ReentrantLock 是一种显式锁,它提供了 synchronized 所不具备的一些高级功能,如公平锁机制、可中断锁、尝试锁定(tryLock),以及能够在不同作用域内灵活地释放锁。ReentrantLock 需要显式的解锁操作,而 synchronized 是隐式锁,当同步代码块结束时,锁会自动释放。