Long time ago, I saved a sentence from a Java reference book: \"Java has no mechanism to handle deadlock. it won\'t even know deadlock occurred.\" (Head First Java 2nd E
If you are running from the command-line and you suspect that you are deadlocked, try ctrl+break in windows (ctrl+\ in unix) to get a thread dump. See http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/gbmps.html
Java can detect deadlocks (although not at run-time, it can still diagnose and report it).
For example, when using a slightly modified version of 'Saurabh M. Chande' code bellow (changed it to Java and added some timing to guarantee a lock on each run). Once you run it and it deadlocks, if you type:
kill -3 PID # where 'PID' is the Linux process ID
It will generate a stack dump, which will include 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"
you have to modify the code a little bit in the Deadlock Class
Deadlock() { Therad t = new Thread(this); // modified t.start(); System.out.println(); //any instruction to delay a.methodA(b); }
Also the above code will not always cause a dead lock, only some times it may happen.
Note that there is a type of deadlock using the concurrent package that is very hard to debug. That is where you have a ReentrantReadWriteLock and one thread grabs the read lock and then (say) tries to enter a monitor held by some other thread that is also waiting to grab the write lock. What makes it especially hard to debug is that there is no record of who has entered a read lock. It is simply a count. The thread might even have thrown an exception and died leaving the read count non-zero.
Here is a sample deadlock that the findDeadlockedThreads method mentioned 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!");
}
}
}
}