interview
java-concurrency
Java 中 ReentrantLock 的实现原理是什么

Java 并发面试题, Java 中 ReentrantLock 的实现原理是什么?

Java 并发面试题, Java 中 ReentrantLock 的实现原理是什么?

QA

Step 1

Q:: Java 中 ReentrantLock 的实现原理是什么?

A:: ReentrantLock 是 java.util.concurrent.locks 包中的一个类,它提供了比 synchronized 更加灵活的锁机制。其实现原理主要基于 AbstractQueuedSynchronizer (AQS) 来管理锁的状态和线程的排队。ReentrantLock 支持公平锁和非公平锁,公平锁按照线程请求的顺序获取锁,非公平锁则允许插队以提高吞吐量。ReentrantLock 还提供了可重入功能,即同一个线程可以多次获取同一把锁,而不会发生死锁。

Step 2

Q:: 如何使用 ReentrantLock?

A:: 使用 ReentrantLock 需要先创建锁对象,然后在需要加锁的代码块前调用 lock() 方法,在代码块后调用 unlock() 方法。通常在 finally 块中调用 unlock() 方法以确保即使在出现异常时也能释放锁。示例代码如下:


ReentrantLock lock = new ReentrantLock();
try {
    lock.lock();
    // 需要保护的临界区代码
} finally {
    lock.unlock();
}

Step 3

Q:: ReentrantLock 和 synchronized 有哪些区别?

A:: 1. ReentrantLock 提供了显式的锁操作,而 synchronized 是隐式的。 2. ReentrantLock 支持公平锁和非公平锁选择,而 synchronized 只能是非公平的。 3. ReentrantLock 可以中断等待锁的线程,而 synchronized 不行。 4. ReentrantLock 提供了一个 tryLock() 方法,可以在获取不到锁时不阻塞线程。 5. synchronized 是 JVM 内置的机制,更简单且易用,而 ReentrantLock 提供了更多高级功能,需要手动管理。

Step 4

Q:: 什么是公平锁和非公平锁?

A:: 公平锁是指多个线程按照请求锁的顺序依次获取锁,非公平锁则允许插队,即后请求的线程可以在某些情况下先获取锁。公平锁可以避免线程饥饿,但吞吐量较低,非公平锁可以提高吞吐量,但可能导致某些线程长时间无法获取锁。ReentrantLock 允许在创建时选择公平性,通过构造函数 ReentrantLock(boolean fair) 来指定。

Step 5

Q:: ReentrantLock 的 tryLock() 方法有什么作用?

A:: tryLock() 方法尝试获取锁,如果锁可用则返回 true,否则立即返回 false 而不阻塞线程。这对于需要尝试获取锁但不希望长时间等待的场景非常有用。还有一个带超时参数的 tryLock(long timeout, TimeUnit unit) 方法,可以在指定的时间内尝试获取锁,如果超时则返回 false。

用途

面试中涉及 ReentrantLock 是因为它在实际生产环境中能够解决高并发情况下的线程同步问题。它提供了比 synchronized 更加灵活和强大的功能,例如中断锁请求、尝试获取锁和公平锁等,适用于对性能和锁的使用有更高要求的场景。在编写高并发程序时,了解并使用 ReentrantLock 能显著提升程序的稳定性和效率。\n

相关问题

🦆
什么是 AbstractQueuedSynchronizer AQS?

AQS 是一个用来构建锁和同步器的框架。它使用一个 FIFO 的等待队列来管理获取锁的线程。AQS 是 ReentrantLock、CountDownLatch、Semaphore 等同步器的基础,实现了对同步状态的独占式和共享式管理。通过子类实现其抽象方法 acquire 和 release 来定义具体的同步器逻辑。

🦆
如何避免死锁?

避免死锁的常见方法包括:1. 避免嵌套锁,即尽量减少持有一个锁的同时去获取另一个锁。2. 使用 tryLock 方法获取锁,这样可以设置获取锁的超时时间。3. 保持锁的顺序,一旦线程尝试获取多个锁,所有线程都以相同的顺序获取锁。4. 使用定时锁机制,当线程无法在指定时间内获取锁时主动释放已经持有的锁。

🦆
什么是可重入锁?

可重入锁指的是同一个线程在外层获取锁后,内层仍然可以获取该锁而不会被阻塞。例如,ReentrantLock 和 synchronized 都是可重入锁。可重入锁的好处在于它避免了死锁的发生,并且允许更复杂的锁定逻辑。

🦆
ReentrantLock 的 Condition 接口是什么?

Condition 是 ReentrantLock 提供的等待/通知机制,与 Object 的 wait 和 notify 相似,但更灵活。每个 Condition 对象与一个锁绑定,Condition 提供了 await() 方法使线程等待,signal() 方法唤醒等待线程。通过 Condition 可以实现更复杂的线程间协作机制,例如实现多个等待队列。