如何获取在对象上拥有Lock的Thread的详细信息

让我们说一个Thread在Java中的同步函数内执行,另一个Thread想要访问相同的方法,但它必须等到第一个Thread完成。 第二个线程如何知道哪个线程在对象上具有锁定。 我想打印第一个Thread的细节,也可能从第一个Thread启动的位置打印出来。

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

或者,您可以使用JMX。 通过线程迭代,找到带有相应getLockedMonitors()getLockedSynchronizers()java.lang.management.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 } } } 

这是用于诊断目的,还是用于要作为应用程序一部分使用的function。 如果是用于诊断,那么其他答案中的各种详细日志记录解决方案可能足以让您前进。 如果你想在function中做到这一点,那么你真的应该使用比synchronized关键字更强大和灵活的东西,比如@Tom提到的ReentrantLock魔法。

我认为不可能这样做。 但是你可以用一些额外的代码做类似的事情:

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