private static Set<Dependency> collectFromDependencyMonitor( ThreadMXBean bean, Serializable locality, Map<Long, ThreadInfo> threadInfos) { HashSet<Dependency> results = new HashSet<Dependency>(); // Convert the held resources into serializable dependencies Set<Dependency<Serializable, Thread>> heldResources = DependencyMonitorManager.getHeldResources(); for (Dependency<Serializable, Thread> dep : heldResources) { Thread thread = dep.getDependsOn(); Serializable resource = dep.getDepender(); ThreadInfo info = threadInfos.get(thread.getId()); if (info == null) { info = bean.getThreadInfo(thread.getId()); } if (info != null) { results.add(new Dependency(resource, new LocalThread(locality, info))); } } Set<Dependency<Thread, Serializable>> blockedThreads = DependencyMonitorManager.getBlockedThreads(); // Convert the blocked threads into serializable dependencies for (Dependency<Thread, Serializable> dep : blockedThreads) { Thread thread = dep.getDepender(); ThreadInfo info = threadInfos.get(thread.getId()); if (info == null) { info = bean.getThreadInfo(thread.getId()); } final Serializable resource = dep.getDependsOn(); results.add(new Dependency(new LocalThread(locality, info), resource)); } return results; }
/** Format deadlock displaying to a user. */ public static String prettyFormat(Collection<Dependency> deadlock) { StringBuilder text = new StringBuilder(); LinkedHashSet<LocalThread> threads = new LinkedHashSet<LocalThread>(); Set<Object> seenDependers = new HashSet<>(); Object lastDependsOn = text; Object lastDepender = text; for (Dependency dep : deadlock) { Object depender = dep.getDepender(); Object dependsOn = dep.getDependsOn(); String dependerString; if (lastDependsOn.equals(depender)) { dependerString = "which"; } else if (lastDepender.equals(depender)) { dependerString = "and"; } else { dependerString = String.valueOf(depender); } lastDepender = depender; lastDependsOn = dependsOn; String also = seenDependers.contains(depender) ? " also" : ""; seenDependers.add(depender); if (depender instanceof LocalThread) { text.append(dependerString) .append(" is") .append(also) .append(" waiting on ") .append(dependsOn) .append("\n"); threads.add((LocalThread) depender); } else if (dependsOn instanceof LocalThread) { text.append(dependerString).append(" is held by thread ").append(dependsOn).append("\n"); threads.add((LocalThread) dependsOn); } else { text.append(dependerString) .append(" is") .append(also) .append(" waiting for ") .append(dependsOn) .append("\n"); } text.append("\n"); } text.append("\nStack traces for involved threads\n"); for (LocalThread threadInfo : threads) { text.append(threadInfo.getLocatility()) .append(":") .append(threadInfo.getThreadStack()) .append("\n\n"); } return text.toString(); }