当前位置: 首页 > 面试题库 >

确定哪个线程拥有监视器

施宏大
2023-03-14
问题内容

对于Java对象,有没有办法告诉哪个线程(或null)当前
拥有其监视器?或者至少是一种方法来判断当前线程是否拥有它?


问题答案:

我自己找到了一些答案。要测试当前线程是否拥有
监视器,是否 存在!
Thread.holdsLock
exists!

if (!Thread.holdsLock(data)) {
    throw new RuntimeException(); // complain
}

这确实非常快(亚微秒),并且从1.4开始就可用。

通常,要测试哪个线程(或线程ID)持有该锁,可以

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. 这有点慢(在我的情况下约为1/2毫秒,大概与线程数成线性关系)。
  2. 它需要Java 1.6和适用于它的VM ThreadMXBean.isObjectMonitorUsageSupported(),因此移植性较差。
  3. 它需要“监视器”安全权限,因此大概无法在沙盒小程序中使用。
  4. 如果需要的话,将线程ID转换为Thread对象并不是一件容易的事,因为我想您必须使用Thread.enumerate然后循环遍历以找出具有ID的对象,但这在理论上是有帮助的竞争条件,因为到您调用枚举时,该线程可能不再存在,或者可能出现了具有相同ID的新线程。
    但是,如果您只想测试当前线程,Thread.holdsLock效果
    很好!否则,的实现 可能比普通的Java监视器提供更多的信息和灵活性 (感谢@ user1252434)。
    java.util.concurrent.locks.Lock


 类似资料:
  • 我有一个Tomcat 9.0.60服务器,运行在Linux上的OpenJDK 1.8.0上,其中netstat-ltpn | grep java显示它侦听的端口不止配置的端口: (我从该列表中删除了所有配置的端口。) 因此,我认为有几个应用程序也打开了“他们自己的”套接字,他们听。我想找出每个端口的哪个Java线程正在侦听,这样我就可以进一步找出应用程序,也许它仍然是必需的,或者只是开发人员忘记的

  • 问题内容: 在运行时是否可以以编程方式检查持有给定对象锁的线程的名称? 问题答案: 您只能说出当前线程是否持有普通锁()。没有本机代码,您将无法获得对具有锁的线程的引用。 但是,如果您要对线程进行任何复杂的处理,则可能需要熟悉java.util.concurrent包。该确实让你得到它的所有者(但其受保护的方法,所以你必须要扩展这个)。根据您的应用程序的不同,很可能是通过使用并发包,您会发现根本不

  • 问题内容: 我在组件上有一个Java MouseListener来检测鼠标的按下。我如何 知道鼠标按下发生在哪个监视器上? 我想要达到的效果是:当用户在 我的应用程序中按下鼠标按钮时,弹出窗口会显示一些信息,直到释放鼠标为止。我想 确保此窗口位于用户单击的位置,但是我需要调整 窗口在当前屏幕上的位置,以便整个窗口 可见。 问题答案: 您可以从获取显示信息。您可以使用它来获取有关本地系统的信息。包括

  • 问题内容: 是否有Linux库可以使我知道哪些进程拥有哪些IP套接字?我想我正在寻找的程序化等效项。最终,我想将透视的数据包与进程关联起来。 更新: 有人建议使用和,但是在我的系统上,每个进程都显示相同的数据,因此无济于事。 问题答案: 我认为您首先必须浏览/ proc / * / fd中打开的fds,例如 然后在/ proc / net / tcp(或/ proc / net / udp)中查找

  • 问题内容: 我有一个LockManager来管理多个线程的锁。有时线程是坏男孩,我必须杀死它们并要求LockManager释放所有锁。但是,由于我无法在Java中使用ReentrantLock,因此无法解锁另一个线程拥有的锁。 我被迫使用锁(不能使用信号灯,这是作业的重点)。是否有任何Java Lock实现可让我解锁其他线程拥有的锁? 到目前为止,我考虑的选项是: 以允许我执行此操作的方式重新实现

  • 我有一个LockManager管理几个线程的锁。有时线程是坏男孩,我必须杀死他们,并要求锁经理释放他们所有的锁。但是,由于我在java中使用ReentrantLock,这是不可能的,我不能解锁另一个线程拥有的锁。 我被迫使用锁(不能使用信号量,这是作业的重点)。是否有Java锁实现允许我解锁其他线程拥有的锁? 到目前为止,我考虑的选择是: null 可重入锁-从另一个线程解锁 从不拥有锁的线程中解