确定哪个线程拥有监视器 [英] Determine which thread owns a monitor
问题描述
对于Java对象,是否有办法告诉哪个线程(或null)当前拥有其监视器?还是至少可以判断当前线程是否拥有它?
Is there a way to tell, for a Java object, which Thread (or null) currently owns its monitor? Or at least a way to tell if the current thread owns it?
推荐答案
I've found out some answers myself. To test if the current thread holds the monitor, Thread.holdsLock
exists!
if (!Thread.holdsLock(data)) {
throw new RuntimeException(); // complain
}
这确实非常快(亚微秒),并且从1.4开始就可用.
This is really fast (sub-microsecond) and has been available since 1.4.
To test in general, which thread (or thread ID) holds the lock, it's possible to do this with java.lang.management
classes (thanks @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;
}
对此有一些警告:
- 这有点慢(在我的情况下约为½毫秒,大概与线程数成线性关系).
- 它需要Java 1.6和
ThreadMXBean.isObjectMonitorUsageSupported()
为true的VM,因此移植性较差. - 它需要监视"安全权限,因此大概无法在沙盒小程序中使用.
- 如果需要的话,将线程ID转换为Thread对象并不是一件容易的事,正如我想的那样,您必须使用Thread.enumerate,然后循环遍历以找出具有ID的对象,但是这具有理论上的竞争条件,因为到您调用枚举时,该线程可能不再存在,或者可能出现了具有相同ID的新线程.
- It's a little slow (~½ millisecond in my case and presumably increases linearly with the number of threads).
- It requires Java 1.6, and a VM for which
ThreadMXBean.isObjectMonitorUsageSupported()
is true, so it's less portable. - It requires the "monitor" security permission so presumably wouldn't work from a sandboxed applet.
- Turning the thread ID into a Thread object, if you need to, is a bit non-trivial, as I imagine you'd have to use Thread.enumerate and then loop through to find out which one has the ID, but this has theoretical race conditions because by the time you call enumerate, that thread might not exist any more, or a new thread might have appeared which has the same ID.
但是,如果您只想测试当前线程,则 Thread.holdsLock
效果很好!否则, java的实现.util.concurrent.locks.Lock
可能比普通的Java监视器提供更多的信息和灵活性(感谢@ user1252434).
But if you only want to test the current thread, Thread.holdsLock
works great! Otherwise, implementations of java.util.concurrent.locks.Lock
may provide more information and flexibility than ordinary Java monitors (thanks @user1252434).
这篇关于确定哪个线程拥有监视器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!