确定哪个线程拥有监视器 [英] Determine which thread owns a monitor

查看:50
本文介绍了确定哪个线程拥有监视器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于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.

要总体测试哪个线程(或线程ID)持有该锁,可以使用

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;
}

对此有一些警告:

  1. 这有点慢(在我的情况下约为½毫秒,大概与线程数成线性关系).
  2. 它需要Java 1.6和 ThreadMXBean.isObjectMonitorUsageSupported()为true的VM,因此移植性较差.
  3. 它需要监视"安全权限,因此大概无法在沙盒小程序中使用.
  4. 如果需要的话,将线程ID转换为Thread对象并不是一件容易的事,正如我想的那样,您必须使用Thread.enumerate,然后循环遍历以找出具有ID的对象,但是这具有理论上的竞争条件,因为到您调用枚举时,该线程可能不再存在,或者可能出现了具有相同ID的新线程.
  1. It's a little slow (~½ millisecond in my case and presumably increases linearly with the number of threads).
  2. It requires Java 1.6, and a VM for which ThreadMXBean.isObjectMonitorUsageSupported() is true, so it's less portable.
  3. It requires the "monitor" security permission so presumably wouldn't work from a sandboxed applet.
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆