Programmatically detect deadlock in java

How can I programmatically determine that a deadlock has occurred in a Java program?

+51
java multithreading concurrency deadlock
Jul 09 '09 at 7:30
source share
9 answers

You can do this programmatically using ThreadMXBean , which comes 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 any thread that performs this deadlock check. Otherwise, if this dead end fails to verify!

By the way, this is what JConsole uses under covers.

+56
Jul 09 '09 at 7:49
source share

One useful hint for research:

If you can catch the application in red and suspect that a deadlock has occurred, go and click "Ctrl-Break" in the java.exe console window (or "Ctrl- \" on Solaris / Linux). The Jvm resets the current state and tracks the trace of all threads, detects dead locks and accurately describes 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) ... 
+9
Jul 09 '09 at 7:43
source share

JArmus is a library for detecting and preventing deadlocks. It includes support for: Thread.join , CyclicBarrier , CountDownLatch , Phaser and ReentrantLock .

To use JArmus, you need to measure your code. Either through one of its tool classes, or automatically with JArmus jarmusc .

java -jar jarmusc.jar yourprogram.jar checkedprogram.jar

Typing yourprogram.jar is the program you want to test. Conclusion - this is the same program with checks to automatically find a dead end.

Barriers need help

Checking deadlocks with the CyclicBarrier , CountDownLatch , Phaser classes is a bit complicated - for example, JConsole cannot detect these types of deadlocks. JArmus needs a little help from you: you must indicate which threads affect the synchronization, we call these registered threads.

As soon as possible, the thread should mark itself as registered. A good place to flag registered threads is the begin Runnable.run method. JArmus.register(latch);

Example

The following program, in which deadlocks are correctly identified by JArmus:

 final CountDownLatch latch = new CountDownLatch(2); final CyclicBarrier barrier = new CyclicBarrier(2); final Queue<Exception> exceptions = new ArrayDeque<>(); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { JArmus.register(barrier); // do not forget to register! JArmus.register(latch); // do not forget to register! latch.countDown(); latch.await(); barrier.await(); } catch (Exception e) { exceptions.add(e); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { JArmus.register(barrier); // do not forget to register! JArmus.register(latch); // do not forget to register! barrier.await(); latch.countDown(); latch.await(); } catch (Exception e) { exceptions.add(e); } } }); t1.start(); t2.start(); 
+3
May 5 '14 at
source share

You might want to consider IBM MTRAT . Prevention is better than cure after all. Multicore Software Development Kit also comes with a lock detection tool.

+2
Jul 09 '09 at 7:32
source share

If you do not require software discovery, you can do this using JConsole ; on the thread tab there is a button "detect deadlock". In JDK6, this detection blocks both internal monitors and juc Lock s

Launch JConsole using the command $JAVA_HOM/bin/jconsole

+2
Jul 09 '09 at 7:48
source share

You can detect inhibited threads programmatically using the 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 information on how to detect inhibited flows.

+2
Mar 09 '15 at 14:28
source share

tempus-fugit also implements it together with a software dumping class. It was implemented using the mbean mechanism mentioned above, and offers a solution based on supermodernity.

+1
Jan 02 '09 at 17:37
source share

Here is the code: http://www.java2s.com/Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm

The magic happens in ThreadMonitor.findDeadlock() :

  public boolean findDeadlock() { long[] tids; if (findDeadlocksMethodName.equals("findDeadlockedThreads") && tmbean.isSynchronizerUsageSupported()) { tids = tmbean.findDeadlockedThreads(); if (tids == null) { return false; } System.out.println("Deadlock found :-"); ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true); for (ThreadInfo ti : infos) { printThreadInfo(ti); printLockInfo(ti.getLockedSynchronizers()); System.out.println(); } } else { tids = tmbean.findMonitorDeadlockedThreads(); if (tids == null) { return false; } ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); for (ThreadInfo ti : infos) { // print thread information printThreadInfo(ti); } } return true; } 

This calls the ThreadMXBean API, which has a different name in Java 5 and 6 (hence the external if() ).

The sample code also allows you to break locks, so you can even break the deadlock.

+1
Nov 16 '11 at 10:15
source share

If you want this to be done at run time, you can use watchdog to do this.

0
Jul 09 '09 at 7:34
source share



All Articles