reentrantlock 是 java 并发包中可重入、可中断、可超时、可公平的显式锁,需手动 lock()/unlock() 且解锁须在 finally 块;支持 lockinterruptibly() 响应中断、trylock() 超时获取、公平模式及 condition 精准线程协作。

ReentrantLock 是 Java 并发包(java.util.concurrent.locks)中提供的可重入、可中断、可超时、可公平的显式锁,相比 synchronized 更灵活,适合复杂并发控制场景。
基本用法:手动加锁与解锁
使用 ReentrantLock 必须显式调用 lock() 加锁、unlock() 解锁,且解锁必须放在 finally 块中,避免因异常导致锁未释放而引发死锁或线程饥饿。
示例:
// 创建非公平锁(默认)
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
// 临界区操作,如修改共享变量
count++;
} finally {
lock.unlock();
}
支持可中断的锁获取
当线程在等待锁时被其他线程调用 interrupt() 中断,lockInterruptibly() 会抛出 InterruptedException 并立即返回,避免无限等待。
适用场景:需要响应外部取消信号(如任务超时、用户主动终止)。
用法要点:
- 必须在 try-catch 中捕获
InterruptedException - 捕获后通常应恢复中断状态:
Thread.currentThread().interrupt(); - 不能在持有锁期间被中断(中断只影响“等待锁”的阶段)
带超时的尝试加锁
使用 tryLock(long timeout, TimeUnit unit) 可设定最多等待多久;若超时仍未获得锁,返回 false,不阻塞线程。
优势:避免线程长时间挂起,提高系统响应性和资源利用率。
典型用法:
if (lock.tryLock(3, TimeUnit.SECONDS)) {
try {
// 成功获取锁,执行业务逻辑
} finally {
lock.unlock();
}
} else {
// 获取锁失败,可降级处理、重试或记录日志
}
公平性与条件队列(Condition)
ReentrantLock 支持构造时传入 true 启用公平模式(FIFO),但会降低吞吐量,仅在确实存在线程饥饿问题时启用。
更实用的是配合 Condition 实现精准的线程协作(替代 wait/notify):
- 每个 ReentrantLock 可创建多个 Condition 实例,实现不同等待条件的分离
-
condition.await()会释放锁并挂起线程;condition.signal()唤醒一个等待线程(需先持有锁) - 务必在 while 循环中检查条件,防止虚假唤醒
例如生产者-消费者中,用 notFull 和 notEmpty 两个 Condition 精确控制:
Lock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();
Condition notFull = lock.newCondition();
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











