ReentrantLock 是 java.util.concurrent.locks 包里的可重入互斥锁,功能比 synchronized 更灵活。提供了超时、中断、轮询、公平锁与非公平锁等功能。
与 synchronized相同,它也是可重入的,内部维护计数器。
核心 API
- 基础上锁/解锁
Lock lock = new ReentrantLock();
lock.lock();
try { /* TODO */ }
finally { lock.unlock(); }
- 非阻塞尝试上锁
if (lock.tryLock()) {
try { /* TODO */ }
finally { lock.unlock(); }
} else {
// 获取失败的退让策略
}
- 限时尝试上锁
if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
try { /* TODO */ }
finally { lock.unlock(); }
}
公平锁与非公平锁
-
构造:
new ReentrantLock(true)为公平锁,false(默认)为非公平。 -
公平锁: 锁被释放后,先来先得,性能较差,为了保证顺序上下文切换更频繁。
-
非公平锁: 锁被释放后,后来的线程可能先获取锁,性能更好,可能导致个别线程长期等待。
与 AQS 的关系
ReentrantLock 是基于AQS「AbstractQueuedSynchronizer」实现,AQS提供队列、阻塞/唤醒与内存语义,ReentrantLock 只需覆写获取/释放的策略。

ReentrantLock 的同步器为 Sync ,Sync 是 AQS 的子类,添加锁和释放锁的大部分操作都在Sync 当中实现。Sync 有两个子类,FairSync 为公平锁 NonfairSync 为非公平锁。
与 synchronized 对比
synchronized- 依赖于 JVM
- 有锁升级机制,在低竞争状态下会比较快
- 语法简洁、异常安全、无忘记
unlock()风险
ReentrantLock- JDK 层面的实现
- 可以通过
lockInterruptibly中断获取 - 可以通过
tryLock限时/非阻塞获取 - 可实现公平锁