一、前言
关于alibaba的dubbo源码包com.alibaba.dubbo.common.utils.JVMUtil虚拟机工具类,将线程内部执行过程进行打印输出,详情参见源码说明。
二、源码说明
package dubbo;@b@@b@import java.io.FileOutputStream;@b@import java.io.OutputStream;@b@import java.lang.management.LockInfo;@b@import java.lang.management.ManagementFactory;@b@import java.lang.management.MonitorInfo;@b@import java.lang.management.ThreadInfo;@b@import java.lang.management.ThreadMXBean;@b@@b@public class JVMUtil {@b@ @b@ public static void jstack(OutputStream stream) throws Exception {@b@ ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();@b@ for (ThreadInfo threadInfo : threadMxBean.dumpAllThreads(true, true)) {@b@ stream.write(getThreadDumpString(threadInfo).getBytes());@b@ }@b@ }@b@@b@ private static String getThreadDumpString(ThreadInfo threadInfo) {@b@ StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" +@b@ " Id=" + threadInfo.getThreadId() + " " +@b@ threadInfo.getThreadState());@b@ if (threadInfo.getLockName() != null) {@b@ sb.append(" on " + threadInfo.getLockName());@b@ }@b@ if (threadInfo.getLockOwnerName() != null) {@b@ sb.append(" owned by \"" + threadInfo.getLockOwnerName() +@b@ "\" Id=" + threadInfo.getLockOwnerId());@b@ }@b@ if (threadInfo.isSuspended()) {@b@ sb.append(" (suspended)");@b@ }@b@ if (threadInfo.isInNative()) {@b@ sb.append(" (in native)");@b@ }@b@ sb.append('\n');@b@ int i = 0;@b@@b@ StackTraceElement[] stackTrace = threadInfo.getStackTrace();@b@ MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors();@b@ for (; i < stackTrace.length && i < 32; i++) {@b@ StackTraceElement ste = stackTrace[i];@b@ sb.append("\tat " + ste.toString());@b@ sb.append('\n');@b@ if (i == 0 && threadInfo.getLockInfo() != null) {@b@ Thread.State ts = threadInfo.getThreadState();@b@ switch (ts) {@b@ case BLOCKED:@b@ sb.append("\t- blocked on " + threadInfo.getLockInfo());@b@ sb.append('\n');@b@ break;@b@ case WAITING:@b@ sb.append("\t- waiting on " + threadInfo.getLockInfo());@b@ sb.append('\n');@b@ break;@b@ case TIMED_WAITING:@b@ sb.append("\t- waiting on " + threadInfo.getLockInfo());@b@ sb.append('\n');@b@ break;@b@ default:@b@ }@b@ }@b@@b@ for (MonitorInfo mi : lockedMonitors) {@b@ if (mi.getLockedStackDepth() == i) {@b@ sb.append("\t- locked " + mi);@b@ sb.append('\n');@b@ }@b@ }@b@ }@b@ if (i < stackTrace.length) {@b@ sb.append("\t...");@b@ sb.append('\n');@b@ }@b@@b@ LockInfo[] locks = threadInfo.getLockedSynchronizers();@b@ if (locks.length > 0) {@b@ sb.append("\n\tNumber of locked synchronizers = " + locks.length);@b@ sb.append('\n');@b@ for (LockInfo li : locks) {@b@ sb.append("\t- " + li);@b@ sb.append('\n');@b@ }@b@ }@b@ sb.append('\n');@b@ return sb.toString();@b@ }@b@ @b@ public static void main(String[] args) throws Exception{@b@ @b@ FileOutputStream fos=new FileOutputStream("C:/WS/1.txt");@b@ jstack(fos);@b@ }@b@@b@}
输出的1.txt内容如下
"Attach Listener" Id=5 RUNNABLE "Signal Dispatcher" Id=4 RUNNABLE "Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@a62fc3@b@@b@ at java.lang.Object.wait(Native Method) - waiting on java.lang.ref.ReferenceQueue$Lock@a62fc3@b@@b@ at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)@b@@b@ at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)@b@@b@ at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:171) "Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@89ae9e@b@ @b@ at java.lang.Object.wait(Native Method) - waiting on java.lang.ref.Reference$Lock@89ae9e@b@@b@ at java.lang.Object.wait(Object.java:485)@b@@b@ at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) "main" Id=1 RUNNABLE@b@@b@ at sun.management.ThreadImpl.dumpThreads0(Native Method)@b@@b@ at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:433)@b@@b@ at dubbo.JVMUtil.jstack(JVMUtil.java:15)@b@@b@ at dubbo.JVMUtil.main(JVMUtil.java:93)