有没有一种方法可以告诉我们,一个Java对象当前被哪个线程(或null)所拥有?或者至少有一种方法可以判断当前线程是否拥有它的监视器?
我已经自己找到了一些答案。要测试当前线程是否持有监视器,请使用Thread.holdsLock
方法!
if (!Thread.holdsLock(data)) {
throw new RuntimeException(); // complain
}
这非常快(亚微秒级别),自1.4版以来就可用。
要测试一般情况下哪个线程(或线程ID)持有锁,可以使用 java.lang.management
类(感谢 @amicngh)。
public static long getMonitorOwner(Object obj) {
if (Thread.holdsLock(obj)) return Thread.currentThread().getId();
for (java.lang.management.ThreadInfo ti :
java.lang.management.ManagementFactory.getThreadMXBean()
.dumpAllThreads(true, false)) {
for (java.lang.management.MonitorInfo mi : ti.getLockedMonitors()) {
if (mi.getIdentityHashCode() == System.identityHashCode(obj)) {
return ti.getThreadId();
}
}
}
return 0;
}
这里有一些注意事项:
ThreadMXBean.isObjectMonitorUsageSupported()
的 VM,因此不太可移植。但是如果你只想测试当前线程,则 Thread.holdsLock
很好用!另外,实现 java.util.concurrent.locks.Lock
可能会提供比普通的 Java monitors 更多的信息和灵活性(感谢 @user1252434)。
不要使用synchronized
,你可能想看一下ReentrantLock,特别是它的getOwner()
和isHeldByCurrentThread()
方法。然而,使用它需要更多的纪律性,因为你必须明确地在finally
块中使用unlock()
。
synchronized(myLock) { .. }
еҲ°myLock.lock(); try { .. } finally {myLock.unlock();}
гҖӮдҪҶжҳҜпјҢдёҺsynchronizedдёҚеҗҢпјҢй”ҒдёҚиғҪд»…д»…жҳҜд»»дҪ•еҜ№иұЎгҖӮ - user1252434ThreadMXBean tBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfo = tBean .getThreadInfo(bean.getAllThreadIds(), true, true);