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。