Java tutorial
//package com.java2s; import java.lang.management.LockInfo; import java.lang.management.ManagementFactory; import java.lang.management.MonitorInfo; import java.lang.management.ThreadInfo; public class Main { /** Builds the stack traces of all the given threadIDs in the buffer. Returns the stack trace of the first thread. */ public static StackTraceElement[] buildStackTraces(long[] threadIds, StringBuilder buffer) { ThreadInfo[] allThreadInfo = ManagementFactory.getThreadMXBean().getThreadInfo(threadIds, true, true); return buildTrace(allThreadInfo, buffer); } /** Builds the stack traces of all the given ThreadInfos in the buffer. Returns the stack trace of the first thread. */ private static StackTraceElement[] buildTrace(ThreadInfo[] allThreadInfo, StringBuilder buffer) { StackTraceElement[] firstStackTrace = null; for (ThreadInfo info : allThreadInfo) { buffer.append("\"" + info.getThreadName() + "\" (id=" + info.getThreadId() + ")"); buffer.append(" " + info.getThreadState() + " on " + info.getLockName() + " owned by "); buffer.append("\"" + info.getLockOwnerName() + "\" (id=" + info.getLockOwnerId() + ")"); if (info.isSuspended()) buffer.append(" (suspended)"); if (info.isInNative()) buffer.append(" (in native)"); buffer.append("\n"); StackTraceElement[] trace = info.getStackTrace(); if (firstStackTrace == null) firstStackTrace = trace; for (int i = 0; i < trace.length; i++) { buffer.append("\tat " + trace[i].toString() + "\n"); if (i == 0) addLockInfo(info, buffer); addMonitorInfo(info, buffer, i); } addLockedSynchronizers(info, buffer); buffer.append("\n"); } return firstStackTrace; } /** Add the LockInfo data to the report. */ private static void addLockInfo(ThreadInfo info, StringBuilder sb) { Thread.State ts = info.getThreadState(); switch (ts) { case BLOCKED: sb.append("\t- blocked on " + info.getLockInfo() + "\n"); break; case WAITING: case TIMED_WAITING: sb.append("\t- waiting on " + info.getLockInfo() + "\n"); break; default: } } /** Add more specific locking details. */ private static void addMonitorInfo(ThreadInfo info, StringBuilder sb, int stackDepth) { MonitorInfo[] monitorInfos = info.getLockedMonitors(); for (int i = 0; i < monitorInfos.length; i++) { MonitorInfo mi = monitorInfos[i]; int depth = mi.getLockedStackDepth(); if (depth == stackDepth) { sb.append("\t- locked " + mi + "\n"); } } } /** Add locked synchronizers data. */ private static void addLockedSynchronizers(ThreadInfo info, StringBuilder sb) { LockInfo[] lockInfo = info.getLockedSynchronizers(); if (lockInfo.length > 0) { sb.append("\n\tNumber of locked synchronizers = " + lockInfo.length + "\n"); for (int i = 0; i < lockInfo.length; i++) { sb.append("\t- " + lockInfo[i] + "\n"); } } } }