Deadlock is a programming situation where two or more threads are blocked forever, this situation arises with at least two threads and two or more resources.
Here I have written a simple program that will cause deadlock scenario and then we will see how to analyze it.
Here is a simple Java Example:
package com.crunchify.tutorials;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
/**
* @author Crunchify.com
*
*/
public class CrunchifyThreadDeadLock {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread crunchifyThread1 = new Thread(new CrunchifySynchronizeThread(obj1, obj2), "crunchifyThread1");
Thread crunchifyThread2 = new Thread(new CrunchifySynchronizeThread(obj2, obj3), "crunchifyThread2");
Thread crunchifyThread3 = new Thread(new CrunchifySynchronizeThread(obj3, obj1), "crunchifyThread3");
crunchifyThread1.start();
Thread.sleep(3000);
crunchifyThread2.start();
Thread.sleep(3000);
crunchifyThread3.start();
}
}
class CrunchifySynchronizeThread implements Runnable {
private Object obj1;
private Object obj2;
public CrunchifySynchronizeThread(Object obj1, Object obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (obj1) {
System.out.println(name + " acquired lock on Object1: " + obj1);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println(name + " acquired lock on Object2: " + obj2);
}
System.out.println(name + " released lock on Object2: " + obj2);
}
System.out.println(name + " released lock on Object1: " + obj1);
System.out.println(name + " Finished Crunchify Deadlock Test.");
}
}
Output:
crunchifyThread1 acquired lock on Object1: java.lang.Object@59e3bddb crunchifyThread2 acquired lock on Object1: java.lang.Object@294e430c crunchifyThread3 acquired lock on Object1: java.lang.Object@246972f1
While your app is hanging like in the example above, you can get a thread dump and see the deadlocked threads.
For example, on Mac, you can either do Ctrl-\ or simply use jstack and process id to get the thread dump which makes it very obvious where the deadlock is.
In this example, the thread dump looks like this:
"crunchifyThread3"
java.lang.Thread.State: RUNNABLE
at sun.management.ThreadImpl.getThreadInfo1(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:174)
at com.crunchify.tutorials.CrunchifySynchronizeThread.getThreadDump(CrunchifyThreadDeadLock.java:64)
at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:50)
at java.lang.Thread.run(Thread.java:722)
"crunchifyThread2"
java.lang.Thread.State: BLOCKED
at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:53)
at java.lang.Thread.run(Thread.java:722)
"crunchifyThread1"
java.lang.Thread.State: BLOCKED
at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:53)
at java.lang.Thread.run(Thread.java:722)
"Signal Dispatcher"
java.lang.Thread.State: RUNNABLE
"Finalizer"
java.lang.Thread.State: WAITING
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
"Reference Handler"
java.lang.Thread.State: WAITING
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
Noticed here BLOCKED and WAITING threads => Deadlock situation here.. In next example will provide simple Java Program to generate above thread dump programmatically.

