package org.simpleframework.http.validate; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.concurrent.CountDownLatch; public class ThreadDumper extends Thread { private static String INDENT = " "; private CountDownLatch latch; private volatile boolean dead; private int wait; public ThreadDumper() { this(10000); } public ThreadDumper(int wait) { this.latch = new CountDownLatch(1); this.wait = wait; } public void waitUntilStarted() throws InterruptedException{ latch.await(); } public void kill(){ try { Thread.sleep(1000); dead = true; dumpThreadInfo(); }catch(Exception e){ e.printStackTrace(); } } public void run() { while(!dead) { try{ latch.countDown(); dumpThreadInfo(); findDeadlock(); Thread.sleep(wait); }catch(Exception e){ e.printStackTrace(); } } } /** * Prints the thread dump information to System.out. */ public static void dumpThreadInfo(){ System.out.println(getThreadInfo()); } public static String getThreadInfo() { ThreadMXBean tmbean = ManagementFactory.getThreadMXBean(); long[] tids = tmbean.getAllThreadIds(); ThreadInfo[] tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); StringWriter str = new StringWriter(); PrintWriter log = new PrintWriter(str); log.println("Full Java thread dump"); for (ThreadInfo ti : tinfos) { printThreadInfo(ti, log); } log.flush(); return str.toString(); } private static void printThreadInfo(ThreadInfo ti, PrintWriter log) { if(ti != null) { StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" + " Id=" + ti.getThreadId() + " in " + ti.getThreadState()); if (ti.getLockName() != null) { sb.append(" on lock=" + ti.getLockName()); } if (ti.isSuspended()) { sb.append(" (suspended)"); } if (ti.isInNative()) { sb.append(" (running in native)"); } log.println(sb.toString()); if (ti.getLockOwnerName() != null) { log.println(INDENT + " owned by " + ti.getLockOwnerName() + " Id=" + ti.getLockOwnerId()); } for (StackTraceElement ste : ti.getStackTrace()) { log.println(INDENT + "at " + ste.toString()); } log.println(); } } /** * Checks if any threads are deadlocked. If any, print * the thread dump information. */ public static boolean findDeadlock() { ThreadMXBean tmbean = ManagementFactory.getThreadMXBean(); long[] tids = tmbean.findMonitorDeadlockedThreads(); if (tids == null) { return false; } else { StringWriter str = new StringWriter(); PrintWriter log = new PrintWriter(str); tids = tmbean.getAllThreadIds(); System.out.println("Deadlock found :-"); ThreadInfo[] tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); for (ThreadInfo ti : tinfos) { printThreadInfo(ti, log); } log.flush(); System.out.println(str.toString()); return true; } } }