Read Also : Difference between Runnable and Callable in Java
What is Deadlock ?
According to Deadlock Oracle docs,Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.When synchronized keyword in java causes the executing thread to block while waiting for the monitor(lock) associated with the specified object,then Deadlock may occur. Since the executing thread might already holds the object which is required by another thread (also in waiting state). In such a case, two threads end up waiting forever for each other object lock.
Program/Code to Create Deadlock between Two Threads in Java
public class DeadLockProgram { // Creating Object Locks static Object ObjectLock1 = new Object(); static Object ObjectLock2 = new Object(); private static class ThreadName1 extends Thread { public void run() { synchronized (ObjectLock1) { System.out.println("Thread 1: Has ObjectLock1"); /* Adding sleep() method so that Thread 2 can lock ObjectLock2 */ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1: Waiting for ObjectLock 2"); /*Thread 1 has ObjectLock1 but waiting for ObjectLock2*/ synchronized (ObjectLock2) { System.out.println("Thread 1: No DeadLock"); } } } } private static class ThreadName2 extends Thread { public void run() { synchronized (ObjectLock2) { System.out.println("Thread 2: Has ObjectLock2"); /* Adding sleep() method so that Thread 1 can lock ObjectLock1 */ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 2: Waiting for ObjectLock 1"); /*Thread 2 has ObjectLock2 but waiting for ObjectLock1*/ synchronized (ObjectLock1) { System.out.println("Thread 2: No DeadLock"); } } } } public static void main(String args[]) { ThreadName1 thread1 = new ThreadName1(); ThreadName2 thread2 = new ThreadName2(); thread1.start(); thread2.start(); } }
Output :
Thread 1: Has ObjectLock1
Thread 2: Has ObjectLock2
Thread 1: Waiting for ObjectLock 2
Thread 2: Waiting for ObjectLock 1
After executing above program you will find the situation of Deadlock as Thread1 waits for ObjectLock2 and Thread2 waits for ObjectLock1.Both threads keep on waiting forever.
How to Avoid Deadlock
The solution to avoid Deadlock is to reshuffle the pattern in which we are accessing the object locks ObjectLock1 and ObjectLock2. In other words, just reverse the order in which we are passing the ObjectLock1 and ObjectLock2 either in ThreadName1 class or ThreadName2 class but not in both. Let's try reshuffling in the above code and see whether we still get the Deadlock or not.public class DeadLockProgram { // Creating Object Locks static Object ObjectLock1 = new Object(); static Object ObjectLock2 = new Object(); private static class ThreadName1 extends Thread { public void run() { synchronized (ObjectLock2) { System.out.println("Thread 1: Has ObjectLock1"); /* Adding sleep() method so that Thread 2 can lock ObjectLock2 */ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1: Waiting for ObjectLock 2"); /*Thread 1 has ObjectLock1 but waiting for ObjectLock2*/ synchronized (ObjectLock1) { System.out.println("Thread 1: No DeadLock"); } } } } private static class ThreadName2 extends Thread { public void run() { synchronized (ObjectLock2) { System.out.println("Thread 2: Has ObjectLock2"); /* Adding sleep() method so that Thread 1 can lock ObjectLock1 */ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 2: Waiting for ObjectLock 1"); /*Thread 2 has ObjectLock2 but waiting for ObjectLock1*/ synchronized (ObjectLock1) { System.out.println("Thread 2: No DeadLock"); } } } } public static void main(String args[]) { ThreadName1 thread1 = new ThreadName1(); ThreadName2 thread2 = new ThreadName2(); thread1.start(); thread2.start(); } }
Output :
Thread 1: Has ObjectLock1
Thread 1: Waiting for ObjectLock 2
Thread 1: No DeadLock
Thread 2: Has ObjectLock2
Thread 2: Waiting for ObjectLock 1
Thread 2: No DeadLock
As you can see in the above output that we do not get the Deadlock. Both threads Thread1 and Thread2 finish executing their task.
Best Practices to Avoid Deadlock
1. Avoiding Nested Locks :
This is one of the most common reason to get the Deadlock. If you share the locks with multiple threads, then Deadlock might occur.Try to avoid sharing locks to multiple threads.2. Avoiding Unnecessary Locks :
We should use lock when required. Unnecessary and frequent use of locks can lead to Deadlock which is fatal for the application.Please mention in comments if you have any questions regarding deadlock.