Programmatic deadlock detection in java
You can do this programmatically using the ThreadMXBean
that ships with the JDK:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.if (threadIds != null) { ThreadInfo[] infos = bean.getThreadInfo(threadIds); for (ThreadInfo info : infos) { StackTraceElement[] stack = info.getStackTrace(); // Log or store stack trace information. }}
Obviously you should try to isolate whichever thread is performing this deadlock check - Otherwise if that thread deadlocks it won't be able to run the check!
Incidentally this is what JConsole is using under the covers.
One useful hint for investigation:
If you can catch the application red handed and suspect a deadlock has occurred, go and press "Ctrl-Break" in the java.exe console window (or "Ctrl-\" on Solaris/Linux).The jvm will dump the current status and stack trace of all threads, find out dead locks and precisely describe them.
It will look something like this:
Full thread dump Java HotSpot(TM) Client VM (1.5.0_09-b03 mixed mode):"[Test Timer] Request Queue" prio=6 tid=0x13d708d0 nid=0x1ec in Object. wait() [0x1b00f000..0x1b00fb68] at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at library.util.AsyncQueue.run(AsyncQueue.java:138) - locked <0x02e70000> (a test.server.scheduler.SchedulerRequestQueue) ...Found one Java-level deadlock:============================="Corba service": waiting to lock monitor 0x13c06684 (object 0x04697d90, a java.lang.Object), which is held by "[Server Connection] Heartbeat Timer""[Server Connection] Heartbeat Timer": waiting to lock monitor 0x13c065c4 (object 0x0467e728, a test.proxy.ServerProxy), which is held by "Corba service"Java stack information for the threads listed above:==================================================="Corba service": at test.proxy.ServerProxy.stopHBWatchDog(ServerProxy:695) - waiting to lock <0x04697d90> (a java.lang.Object) ...
You can detect the deadlocked threads programmatically using ThreadMXBean class.Here is the code,
ThreadMXBean bean = ManagementFactory.getThreadMXBean(); long ids[] = bean.findMonitorDeadlockedThreads(); if(ids != null) { ThreadInfo threadInfo[] = bean.getThreadInfo(ids); for (ThreadInfo threadInfo1 : threadInfo) { System.out.println(threadInfo1.getThreadId()); //Prints the ID of deadlocked thread System.out.println(threadInfo1.getThreadName()); //Prints the name of deadlocked thread System.out.println(threadInfo1.getLockName()); //Prints the string representation of an object for which thread has entered into deadlock. System.out.println(threadInfo1.getLockOwnerId()); //Prints the ID of thread which currently owns the object lock System.out.println(threadInfo1.getLockOwnerName()); //Prints name of the thread which currently owns the object lock. } } else { System.out.println("No Deadlocked Threads"); }
Click here for more info on how to detect the deadlocked threads.