ReentrantLock 通过 getOwner() 获取当前持有锁的线程(可能为 null),配合 getHoldCount() 判断重入深度,并可用 getQueuedThreads() 查看等待队列,结合 JMX 或日志实现生产环境监控。

ReentrantLock 本身不直接暴露“当前持有锁的线程”这一信息,但可以通过其内置的 getOwner() 方法获取当前持有锁的线程对象(可能为 null),这是最常用且官方支持的监控方式。
使用 getOwner() 获取持有锁的线程
ReentrantLock 提供了 getOwner() 方法,返回当前持有该锁的线程(非公平锁或公平锁在锁被占用时均适用)。注意:该方法仅反映调用时刻的瞬时状态,不保证线程仍在执行 —— 它只是快照。
- 若锁未被任何线程持有,返回
null - 若被某线程持有,返回对应
Thread实例,可通过getName()、getId()等获取标识信息 - 该方法无需加锁即可调用,线程安全
配合 getHoldCount() 判断重入深度
单靠 getOwner() 只知道“谁拿了锁”,但不知道“拿了几次”。对可重入锁,同一线程可多次 lock()。此时可用 getHoldCount() 辅助判断:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
getHoldCount()返回当前持有锁的线程已成功获取该锁的次数(即重入深度) - 若
getOwner() == Thread.currentThread(),则getHoldCount()≥ 1 - 若
getOwner() != null且getHoldCount() == 0,说明该线程已释放锁但尚未被其他线程抢占(极短暂窗口,通常不会出现)
通过 getQueuedThreads() 观察等待队列
若想了解“谁在排队等锁”,可调用 getQueuedThreads()(返回等待获取该锁的线程列表,按 FIFO 排序)或更轻量的 hasQueuedThreads() 判断是否有等待者:
立即学习“Java免费学习笔记(深入)”;
- 返回的是可能正在阻塞等待的线程集合(包括因 tryLock 失败而轮询的线程,但不包含刚调用 lock() 尚未进入队列的线程)
- 注意:该列表不包含已获取锁的线程,只反映竞争者
- 适用于排查锁争用瓶颈,比如发现大量线程排队,结合
getOwner()可定位持有者是否长时间未释放
启用 JMX 或使用 java.util.concurrent.locks.LockSupport 配合诊断
生产环境推荐结合 JVM 自带机制做长期监控:
- ReentrantLock 的实现类(如
Sync子类)内部状态可通过 JMX 暴露(需自定义 MBean 或使用第三方工具如 VisualVM、JConsole 查看java.util.concurrent.locks相关 MXBean) - 也可在关键 lock/unlock 处打日志,记录
Thread.currentThread().getName()和时间戳,配合getOwner()快照做交叉验证 - 避免在高频路径中频繁调用
getOwner(),虽是轻量操作,但大量调用仍影响性能

















