[ACCEPTED]-Deadlock detection in Java-deadlock

Accepted answer
Score: 85

Since JDK 1.5 there are very useful methods 5 in the java.lang.management package to find and inspect deadlocks 4 that occurs. See the findMonitorDeadlockedThreads() and findDeadlockedThreads() method of the 3 ThreadMXBean class.

A possible way to use this is to 2 have a separate watchdog thread (or periodic 1 task) that does this.

Sample code:

  ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
  long[] ids = tmx.findDeadlockedThreads();
  if (ids != null) {
     ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
     System.out.println("The following threads are deadlocked:");
     for (ThreadInfo ti : infos) {
        System.out.println(ti);
     }
  }
Score: 19

JConsole is able to detect deadlocks in a running 1 application.

Score: 12

JDK 5 and 6 will dump held lock information 13 in a full thread dump (obtained with kill 12 -3, jstack, jconsole, etc). JDK 6 even 11 contains information about ReentrantLock 10 and ReentrantReadWriteLock. It is possible 9 from this information to diagnose a deadlock 8 by finding a lock cycle: Thread A holds 7 lock 1, Thread B holds lock 2, and either 6 A is requesting 2 or B is requesting 1. From 5 my experience, this is usually pretty obvious.

Other 4 analysis tools can actually find potential 3 deadlocks even if they don't occur. Thread 2 tools from vendors like OptimizeIt, JProbe, Coverity, etc 1 are good places to look.

Score: 11

Note that there is a type of deadlock using 13 the concurrent package that is very hard 12 to debug. That is where you have a ReentrantReadWriteLock 11 and one thread grabs the read lock and then 10 (say) tries to enter a monitor held by some 9 other thread that is also waiting to grab 8 the write lock. What makes it especially 7 hard to debug is that there is no record 6 of who has entered a read lock. It is simply 5 a count. The thread might even have thrown 4 an exception and died leaving the read count 3 non-zero.

Here is a sample deadlock that 2 the findDeadlockedThreads method mentioned 1 earlier won't get:

import java.util.concurrent.locks.*;
import java.lang.management.*;

public class LockTest {

    static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public static void main(String[] args) throws Exception {
        Reader reader = new Reader();
        Writer writer = new Writer();
        sleep(10);
        System.out.println("finding deadlocked threads");
        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
        long[] ids = tmx.findDeadlockedThreads();
        if (ids != null) {
            ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
            System.out.println("the following threads are deadlocked:");
            for (ThreadInfo ti : infos) {
                System.out.println(ti);
            }
        }
        System.out.println("finished finding deadlocked threads");
    }

    static void sleep(int seconds) {
        try {
            Thread.currentThread().sleep(seconds*1000);
        } catch (InterruptedException e) {}
    }

    static class Reader implements Runnable {
        Reader() {
            new Thread(this).start();
        }
        public void run() {
            sleep(2);
            System.out.println("reader thread getting lock");
            lock.readLock().lock();
            System.out.println("reader thread got lock");
            synchronized (lock) {
                System.out.println("reader thread inside monitor!");
                lock.readLock().unlock();
            }
        }
    }

    static class Writer implements Runnable {
        Writer() {
            new Thread(this).start();
        }
        public void run() {
            synchronized (lock) {
                sleep(4);
                System.out.println("writer thread getting lock");
                lock.writeLock().lock();
                System.out.println("writer thread got lock!");
            }
        }
    }
}
Score: 6

In general java does not offer deadlock 11 detection. The synchronized keyword and 10 built in monitors make it somewhat more 9 difficult to reason about deadlock than 8 in languages with explicit locking.

I would 7 suggest migrating to using java.util.concurrent.Lock 6 locks and the like in order to make your 5 locking schemes easier to reason about. In 4 fact you could easily make your own implementation 3 of the lock interface with deadlock detection. The 2 algorithm is to basically traverse the lock 1 dependency graph and look for a cycle.

Score: 5

Deadlocks can be avoided if you follow a 22 simple rule: have all threads claim and 21 release their locks in the same order. In 20 this way, you never get into a situation 19 where a deadlock can occur.

Even the dining 18 philosophers problem can be seen as a violation 17 of this rule as it uses relative concepts 16 of left and right spoon which result in 15 different threads using different allocation 14 orders of the spoons. If the spoons were 13 numbered uniquely and the philosophers all 12 tried to get the lowest numbered spoon first, deadlock 11 would be impossible.

In my opinion, prevention 10 is better than cure.

This is one of the two 9 guidelines I like to follow to ensure threads 8 work properly. The other is ensuring each 7 thread is solely responsible for its own execution 6 as it's the only one fully aware of what 5 it's doing at any point in time.

So that 4 means no Thread.stop calls, use a global flag (or message 3 queue or something like that) to tell another 2 thread you want action taken. Then let 1 that thread do the actual work.

Score: 5

Java can detect deadlocks (although not 8 at run-time, it can still diagnose and report 7 it).

For example, when using a slightly 6 modified version of 'Saurabh M. Chande' code 5 bellow (changed it to Java and added some 4 timing to guarantee a lock on each run). Once 3 you run it and it deadlocks, if you type:

kill -3 PID   # where 'PID' is the Linux process ID

It 2 will generate a stack dump, which will include 1 the following information:

Found one Java-level deadlock:
=============================
"Thread-0":
     waiting to lock monitor 0x08081670 (object 0x7f61ddb8, a Deadlock$A),
     which is held by "main"
"main":
      waiting to lock monitor 0x080809f0 (object 0x7f61f3b0, a Deadlock$B),
      which is held by "Thread-0"
Score: 4

If you are on Java 5 you can call the method 8 findMonitorDeadlockedThreads() on the ThreadMXBean which you can get through 7 a call of java.lang.management.ManagementFactory.getThreadMXBean(). This will find deadlocks caused 6 by object monitors only. On Java 6 there's 5 findDeadlockedThreads() which will also find deadlocks caused by 4 "ownable synchronizers (for example ReentrandLock and 3 ReentrantReadWriteLock).

Be aware that it will probably be expensive 2 to call these methods, so they should be 1 used for troubleshooting purposes only.

Score: 3

Not exactly what you asked, but when a deadlock 4 does occur, you can do a "kill -3" on the process 3 id and it dumps a thread dump to stdout. Also, the 2 1.6 jvm has some tools to do the same thing 1 in a gui manner.

Score: 3

If you are running from the command-line 3 and you suspect that you are deadlocked, try 2 ctrl+break in windows (ctrl+\ in unix) to 1 get a thread dump. See http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/gbmps.html

Score: 3

Dr. Heinz Kabutz of JavaSpecialists has 5 written an entertaining and informative 4 newsletter issue on Java deadlocks and describes something called a ThreadMXBean 3 in another newsletter issue. Between those, you should get a good 2 idea of the issues and some pointers to 1 doing your own instrumentation.

Score: 2

If you're debugging in eclipse, you can 4 pause the application (select the app in 3 the debug view and the little || button 2 on the debug toolbar) and then it can report 1 deadlocks.

See http://runnerwhocodes.blogspot.com/2007/10/deadlock-detection-with-eclipse.html for an example.

Score: 2

Java 1.8 onwards, you can easily find if 4 your program has a deadlock by using jcmd command 3 on your terminal.

  1. Run jcmd on your terminal: It lists all the programs (PID and name) which are using Java.
  2. Now, run jcmd <PID> Thread.print: This will print the thread dump on your console and will also print if your program has a deadlock.

You can analyse your Java 2 program with more jcmd options listed by command 1 jcmd <PID> help

Score: 0

Java 5 introduced ThreadMXBean - an interface 8 that provides various monitoring methods 7 for threads. ... The difference is that 6 findDeadlockedThreads can also detect deadlocks 5 caused by owner locks (java.util.concurrent), while 4 findMonitorDeadlockedThreads can only detect 3 monitor locks (i.e. synchronized blocks)

Or 2 you can detect it programatically, refer 1 this https://dzone.com/articles/how-detect-java-deadlocks

More Related questions