【发布时间】:2009-07-28 06:04:17
【问题描述】:
假设一个线程在 Java 中的同步函数中执行,另一个线程想要访问相同的方法,但它必须等到第一个线程完成。 第二个线程如何知道哪个线程在对象上具有锁定。 我想打印第一个线程的详细信息,并且可能从第一个线程的启动位置打印出来。
【问题讨论】:
标签: java multithreading
假设一个线程在 Java 中的同步函数中执行,另一个线程想要访问相同的方法,但它必须等到第一个线程完成。 第二个线程如何知道哪个线程在对象上具有锁定。 我想打印第一个线程的详细信息,并且可能从第一个线程的启动位置打印出来。
【问题讨论】:
标签: java multithreading
如果您使用的是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
}
}
}
【讨论】:
这是用于诊断目的,还是用于您想要用作应用程序一部分的功能。如果是用于诊断,那么此处其他答案中的各种详细日志记录解决方案可能足以让您继续前进。如果您想将此作为功能的一部分,那么您确实应该使用比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");
}
【讨论】: