ReentrantLock天然支持可重入,同一线程可多次lock()不阻塞,计数器递增,需对应次数unlock()才释放;必须用try-finally确保解锁;可通过isHeldByCurrentThread()和getHoldCount()检查重入状态。

ReentrantLock 本身就是一个可重入锁,只要正确使用 lock() 和 unlock() 配对,就能天然支持可重入——不需要额外配置或特殊写法。
理解“可重入”的表现
同一个线程可以多次调用 lock() 而不会被阻塞;每次 lock() 都会增加内部计数器,对应地,必须调用相同次数的 unlock() 才真正释放锁。
- 第一次
lock():计数器变为 1,线程获得锁 - 同一线程再次
lock():计数器变为 2,不阻塞 - 调用一次
unlock():计数器减为 1,锁仍被持有 - 再调用一次
unlock():计数器归零,锁被完全释放
基本使用模式(必须 try-finally)
为避免因异常导致锁未释放,必须在 try-finally 中调用 unlock():
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// 临界区代码
doSomething();
// 可重入示例:内部方法也尝试获取同一把锁
innerMethod(); // 内部也调用 lock.lock() → 成功,计数+1
} finally {
lock.unlock(); // 注意:这里只解一次,需确保 unlock 次数匹配 lock 次数
}
手动实现多层可重入调用
若业务逻辑中存在嵌套加锁需求(如递归、委托调用),可显式复用同一锁实例:
立即学习“Java免费学习笔记(深入)”;
- 所有嵌套方法都使用同一个
ReentrantLock实例 - 每个加锁点都配对
lock()和unlock() - 不要在不同方法中创建新锁实例,否则失去可重入语义
例如:
void outer() {
lock.lock();
try {
// ...
inner();
} finally {
lock.unlock();
}
}
void inner() {
lock.lock(); // 同一线程,同一锁 → 可重入成功
try {
// ...
} finally {
lock.unlock();
}
}
检查与调试可重入状态
可通过以下方法验证或排查可重入行为:
-
lock.isHeldByCurrentThread():判断当前线程是否持有该锁 -
lock.getHoldCount():返回当前线程对该锁的持有次数(即重入深度) -
lock.getQueueLength():查看等待队列长度,辅助判断是否发生意外阻塞
比如在临界区内打印:System.out.println("Hold count: " + lock.getHoldCount());


















