/** * */ package org.pushingpixels.tracing; import java.awt.AWTEvent; import java.awt.event.InvocationEvent; import java.lang.management.*; import java.util.*; import javax.management.MBeanServer; import javax.management.ObjectName; class TracingEventQueueThreadJMX extends Thread { private long thresholdDelay; private long initTime; private Map eventTimeMap; private ThreadMXBean threadBean; public TracingEventQueueThreadJMX(long thresholdDelay) { this.initTime= System.currentTimeMillis(); this.thresholdDelay = thresholdDelay; this.eventTimeMap = new HashMap(); try { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objName = new ObjectName( ManagementFactory.THREAD_MXBEAN_NAME); Set mbeans = mbeanServer.queryNames(objName, null); for (ObjectName name : mbeans) { this.threadBean = ManagementFactory.newPlatformMXBeanProxy( mbeanServer, name.toString(), ThreadMXBean.class); } } catch (Exception e) { e.printStackTrace(); } } public synchronized void eventDispatched(AWTEvent event) { this.eventTimeMap.put(event, System.currentTimeMillis()); } public synchronized void eventProcessed(AWTEvent event) { this.checkEventTime(event, System.currentTimeMillis(), this.eventTimeMap.get(event),"B"); this.eventTimeMap.put(event,null); } private void checkEventTime(AWTEvent event, long currTime, long startTime, String callSite ) { if ( callSite.equals("A") ) { return; } long currProcessingTime = currTime - startTime; if (currProcessingTime >= this.thresholdDelay) { long deltaTime= currTime - initTime; String msg= " is taking too much time on EDT ("; if ( callSite.equals("B") ) { msg= " took too much time on EDT ("; } System.err.println( String.format( "@%8.1fs: ", deltaTime/1000. ) + "Event [" + event.hashCode() + "] " + event.getClass().getName() + msg + currProcessingTime + " ms)"); if ( event instanceof InvocationEvent ) { System.err.println( "InvocationEvent.paramString: "+((InvocationEvent)event).paramString() ); } boolean verbose= true; if (this.threadBean != null) { long threadIds[] = threadBean.getAllThreadIds(); for (long threadId : threadIds) { ThreadInfo threadInfo = threadBean.getThreadInfo(threadId, Integer.MAX_VALUE); if (threadInfo.getThreadName().startsWith("AWT-EventQueue")) { if ( verbose ) System.err.println(threadInfo.getThreadName() + " / " + threadInfo.getThreadState()); StackTraceElement[] stack = threadInfo.getStackTrace(); for (StackTraceElement stackEntry : stack) { if ( verbose ) { System.err.println("\t" + stackEntry.getClassName() + "." + stackEntry.getMethodName() + " [" + stackEntry.getLineNumber() + "]"); } else { if ( stackEntry.getClassName().contains("autoplot") || stackEntry.getClassName().contains("das2") ) { System.err.println("\t" + stackEntry.getClassName() + "." + stackEntry.getMethodName() + " [" + stackEntry.getLineNumber() + "]"); break; } } } } } long[] deadlockedThreads = threadBean.findDeadlockedThreads(); if ((deadlockedThreads != null) && (deadlockedThreads.length > 0)) { System.err.println("Deadlocked threads:"); for (long threadId : deadlockedThreads) { ThreadInfo threadInfo = threadBean.getThreadInfo( threadId, Integer.MAX_VALUE); System.err.println(threadInfo.getThreadName() + " / " + threadInfo.getThreadState()); StackTraceElement[] stack = threadInfo.getStackTrace(); for (StackTraceElement stackEntry : stack) { System.err.println("\t" + stackEntry.getClassName() + "." + stackEntry.getMethodName() + " [" + stackEntry.getLineNumber() + "]"); } } } } } } @Override public void run() { while (true) { long currTime = System.currentTimeMillis(); synchronized (this) { for (Map.Entry entry : this.eventTimeMap .entrySet()) { AWTEvent event = entry.getKey(); if (entry.getValue() == null) continue; long startTime = entry.getValue(); this.checkEventTime(event, currTime, startTime,"A"); } } try { Thread.sleep(100); } catch (InterruptedException ie) { } } } }