我使用ThreadMXBean
使用dumpAllThreads(true, true)
报告线程列表:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
for (ThreadInfo info : bean.dumpAllThreads(true, true)) {
writer.append(ThreadInfos.toStringFull(info));
}
但是,转储中的某些线程似乎不存在,更糟糕的是,它们似乎拥有自己的监视器!:
"pool-24-thread-16" Id=99 WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@a8bb29 owned by "ForkJoinPool-2-worker-13" Id=114
at sun.misc.Unsafe.park(Native Method)
- waiting on java.util.concurrent.locks.ReentrantLock$NonfairSync@a8bb29
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Unknown Source)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(Unknown Source)
at java.util.concurrent.locks.ReentrantLock.lock(Unknown Source)
在此示例中,ForkJoinPool-2-worker-13
未在线程转储中列出,因此很难看到它是如何抓住ReentrantLock$NonfairSync@a8bb29
的。
我一定是在犯一些愚蠢的错误!我如何找到这些线程如何获得了这些锁?
我不确定为什么您的方法行不通。我希望它能工作。但是,如果您使用的是OpenJDK或Oracle JRE,请尝试另一种方法。
kill -3 <pid of java>
这会将所有线程及其锁转储到Java进程的标准中。 (它还会转储对象直方图,但您可以忽略它。)