Java 如何获取拥有对象锁的线程的详细信息

Java 如何获取拥有对象锁的线程的详细信息,java,multithreading,Java,Multithreading,假设一个线程在Java中的同步函数中执行,另一个线程希望访问相同的方法,但它必须等到第一个线程完成。 第二个线程如何知道哪个线程在对象上拥有锁。 我想打印第一个线程的详细信息,可能还有第一个线程的起始位置。如果您使用的是java.util.concurrent.locks.ReentrantLock,则子类可以调用getOwner 或者,您可以使用JMX。使用适当的getLockedMonitors()或getLockedSynchronizers()遍历线程以查找java.lang.manag

假设一个线程在Java中的同步函数中执行,另一个线程希望访问相同的方法,但它必须等到第一个线程完成。 第二个线程如何知道哪个线程在对象上拥有锁。
我想打印第一个线程的详细信息,可能还有第一个线程的起始位置。

如果您使用的是
java.util.concurrent.locks.ReentrantLock
,则子类可以调用
getOwner


或者,您可以使用JMX。使用适当的
getLockedMonitors()
getLockedSynchronizers()
遍历线程以查找
java.lang.management.ThreadInfo

如果您使用的是
java.util.concurrent.locks.ReentrantLock
,那么子类可以调用
getOwner


或者,您可以使用JMX。使用适当的
getLockedMonitors()
getLockedSynchronizers()
遍历线程以查找
java.lang.management.ThreadInfo

我认为这是不可能的。但是,您可以通过一些额外的编码执行类似的操作:

public void myFunction() {
  System.out.println("" + Thread.currentThread() + " entering sync @ myFunction");
  synchronized(this) {
    System.out.println("" + Thread.currentThread() + " entered sync @ myFunction");

    ...

    System.out.println("" + Thread.currentThread() + " leaving sync @ myFunction");
  }
  System.out.println("" + Thread.currentThread() + " left sync @ myFunction");
}

我认为这是不可能的。但是,您可以通过一些额外的编码执行类似的操作:

public void myFunction() {
  System.out.println("" + Thread.currentThread() + " entering sync @ myFunction");
  synchronized(this) {
    System.out.println("" + Thread.currentThread() + " entered sync @ myFunction");

    ...

    System.out.println("" + Thread.currentThread() + " leaving sync @ myFunction");
  }
  System.out.println("" + Thread.currentThread() + " left sync @ myFunction");
}

这有点棘手,几乎是Tom Hawtin写的,但在dumpAllThreads中获取ThreadInfo时,必须明确请求监视器信息。 比如:

    Object lock = ...
    ThreadMXBean mx = ManagementFactory.getThreadMXBean();
    ThreadInfo[] allInfo = mx.dumpAllThreads(true, false);
    for (ThreadInfo threadInfo : allInfo) {
        MonitorInfo[] monitors = threadInfo.getLockedMonitors();
        for (MonitorInfo monitorInfo : monitors) {
            if (monitorInfo.getIdentityHashCode() == System.identityHashCode(lock)) {
                StackTraceElement[] stackTrace = threadInfo.getStackTrace();
                // use the the Information from threadInfo
            }
        }
    }

这有点棘手,几乎是Tom Hawtin写的,但在dumpAllThreads中获取ThreadInfo时,必须明确请求监视器信息。 比如:

    Object lock = ...
    ThreadMXBean mx = ManagementFactory.getThreadMXBean();
    ThreadInfo[] allInfo = mx.dumpAllThreads(true, false);
    for (ThreadInfo threadInfo : allInfo) {
        MonitorInfo[] monitors = threadInfo.getLockedMonitors();
        for (MonitorInfo monitorInfo : monitors) {
            if (monitorInfo.getIdentityHashCode() == System.identityHashCode(lock)) {
                StackTraceElement[] stackTrace = threadInfo.getStackTrace();
                // use the the Information from threadInfo
            }
        }
    }

这是用于诊断目的,还是用于希望作为应用程序一部分使用的功能。如果是为了诊断,那么这里的其他答案中的各种详细日志解决方案可能足以让您继续。如果您想将此作为功能的一部分,那么您真的应该使用比
synchronized
关键字更健壮、更灵活的方法,例如@Tom提到的
ReentrantLock
向导。

这是用于诊断目的,还是用于希望作为应用程序一部分使用的功能。如果是为了诊断,那么这里的其他答案中的各种详细日志解决方案可能足以让您继续。如果您想将此作为功能的一部分,那么您真的应该使用比
synchronized
关键字更健壮、更灵活的方法,例如@Tom提到的
ReentrantLock
向导