java对象锁持有者信息按锁状态分层存储:偏向锁存于mark word,轻量级锁隐含在栈中lock record,重量级锁由monitor.owner维护;jvm不提供标准api直接查询,需用jstack、jmc等工具或自定义可追踪锁。

Java 中对象锁的持有者线程信息不直接对外暴露,但其存储机制是明确且分层的,取决于当前锁所处的状态(无锁 → 偏向锁 → 轻量级锁 → 重量级锁)。验证方式也因状态而异,不能一概而论。
锁持有者信息的存储位置
-
偏向锁阶段
持有者线程 ID 直接存于对象头的 Mark Word 中:- 31 位存储 JVM 内部线程 ID(非 OS 线程 ID)
-
biased_lock=1且lock=001标识该状态 - 同一线程重复进入时,仅比对 Mark Word 中的 thread ID,无需竞争
轻量级锁阶段
Mark Word 不再存线程 ID,而是存一个指向栈中锁记录(Lock Record)的指针;
锁记录位于获取锁的线程的虚拟机栈帧内,其中包含原 Mark Word 备份及线程相关信息;
→ 持有者隐含在“哪个线程的栈里存在该锁记录”中。重量级锁阶段
Mark Word 存的是指向 Monitor 对象的指针;
Monitor 内部有owner字段(类型为Thread*),真实记录当前持有锁的线程引用;
此时锁持有者信息由 Monitor 维护,而非对象头。
注意:JVM 不提供标准 API(如
obj.getLockOwner())直接读取这些字段。Mark Word 和 Monitor 是 JVM 内部结构,用户代码无法直接访问。
如何验证当前锁被哪个线程持有
✅ 推荐方式:使用 JVM 工具链(生产可用)
-
jstack + 线程 dump
执行jstack <pid></pid>,查找类似以下片段:"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f8b4c00a000 nid=0x3a17 waiting for monitor entry at com.example.Test.lockMethod(Test.java:15) - waiting to lock (a java.lang.Object) "main" #1 prio=5 os_prio=0 tid=0x00007f8b4c001000 nid=0x3a13 owning monitor at com.example.Test.main(Test.java:10)
关键线索:
owning monitor表示持有锁,waiting to lock表示阻塞等待。 JMC(Java Mission Control)或 VisualVM
启用“线程”页签,可直观看到 synchronized 锁的 owner 和 blocked 线程列表。
✅ 编程方式:自定义可追踪锁(开发/调试用)
若需运行时主动查询,建议绕过内置锁,封装可审计的锁:
public class TrackedReentrantLock extends ReentrantLock {
private final ThreadLocal<thread> holder = ThreadLocal.withInitial(() -> null);
@Override
public void lock() {
super.lock();
holder.set(Thread.currentThread());
}
@Override
public void unlock() {
if (Thread.currentThread() != holder.get()) {
throw new IllegalMonitorStateException("Not owner");
}
holder.remove();
super.unlock();
}
public Thread getOwner() {
return holder.get();
}
}</thread>
→ 此类可随时调用 getOwner() 获取当前持有者,但仅适用于你控制锁实例的场景(不能用于 synchronized)。
❌ 不可行方式
尝试反射读取
Object的 Mark Word 或 Monitor 字段:
这些字段不在 Java 层公开,且受 JVM 内存模型和安全限制保护,反射失败或返回无效值。依赖
Thread.holdsLock(obj):
它只能判断当前线程是否持有该对象锁,无法得知其他线程是否持有。
小结关键点
- 锁持有者信息按锁状态分散存储:偏向锁 → Mark Word;轻量级锁 → 栈中 Lock Record;重量级锁 → Monitor.owner
- JVM 不提供标准接口查询任意对象的锁持有者,必须借助外部工具(jstack)或自建可追踪锁
-
synchronized的锁归属始终由 JVM 运行时维护,应用层应聚焦逻辑正确性,而非实时探查锁状态
不复杂但容易忽略:多数锁问题靠线程 dump 就能定位,不必强行编码反查。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











