Table of Contents
Deadlock in Java is a part of multithreading. Deadlock can occur in a situation when a thread is waiting for an object lock, that is acquired by another thread and second thread is waiting for an object lock that is acquired by first thread. Since, both threads are waiting for each other to release the lock, the condition is called deadlock.
Example of Deadlock in Java
1: What is the default value of a boolean in Java?
TestDeadlockExample1.java
- public class TestDeadlockExample1 {
-   public static void main(String[] args) {
-     final String resource1 = “ratan jaiswal”;
-     final String resource2 = “vimal jaiswal”;
-     // t1 tries to lock resource1 then resource2
-     Thread t1 = new Thread() {
-       public void run() {
-           synchronized (resource1) {
-            System.out.println(“Thread 1: locked resource 1”);
-            try { Thread.sleep(100);} catch (Exception e) {}
-            synchronized (resource2) {
-             System.out.println(“Thread 1: locked resource 2”);
- Â Â Â Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â }
- Â Â Â Â };
-     // t2 tries to lock resource2 then resource1
-     Thread t2 = new Thread() {
-       public void run() {
-         synchronized (resource2) {
-           System.out.println(“Thread 2: locked resource 2”);
-           try { Thread.sleep(100);} catch (Exception e) {}
-           synchronized (resource1) {
-             System.out.println(“Thread 2: locked resource 1”);
- Â Â Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â }
- Â Â Â Â };
- Â Â Â Â t1.start();
- Â Â Â Â t2.start();
- Â Â }
- }
Output:
Thread 1: locked resource 1 Thread 2: locked resource 2
Learn Coding in your Language! Enroll Here!
More Complicated Deadlocks
A deadlock may also include more than two threads. The reason is that it can be difficult to detect a deadlock. Here is an example in which four threads have deadlocked:
Thread 1 locks A, waits for B
Thread 2 locks B, waits for C
Thread 3 locks C, waits for D
Thread 4 locks D, waits for A
Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3 waits for thread 4, and thread 4 waits for thread 1.
How to avoid deadlock?
A solution for a problem is found at its roots. In deadlock it is the pattern of accessing the resources A and B, is the main issue. To solve the issue we will have to simply re-order the statements where the code is accessing shared resources.
DeadlockSolved.java
- public class DeadlockSolved {
-     public static void main(String ar[]) {
-         DeadlockSolved test = new DeadlockSolved();
-         final resource1 a = test.new resource1();
-         final resource2 b = test.new resource2();
- Â Â Â //Â Thread-1
- Runnable b1 = new Runnable() {
-     public void run() {
-         synchronized (b) {
-             try {
-                 /* Adding delay so that both threads can start trying to lock resources */
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Thread.sleep(100);
-             } catch (InterruptedException e) {
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â e.printStackTrace();
- Â Â Â Â Â Â Â Â Â Â Â Â }
-             // Thread-1 have resource1 but need resource2 also
-             synchronized (a) {
-                 System.out.println(“In block 1”);
- Â Â Â Â Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â Â Â }
- Â Â Â Â }
- };
- //Â Thread-2
- Runnable b2 = new Runnable() {
-     public void run() {
-         synchronized (b) {
-             // Thread-2 have resource2 but need resource1 also
-             synchronized (a) {
-                 System.out.println(“In block 2”);
- Â Â Â Â Â Â Â Â Â Â Â Â }
- Â Â Â Â Â Â Â Â }
- Â Â Â Â }
- };
-         new Thread(b1).start();
-         new Thread(b2).start();
- Â Â Â Â }
- Â Â Â Â //Â resource1
-     private class resource1 {
-         private int i = 10;
-         public int getI() {
-             return i;
- Â Â Â Â Â Â Â Â }
-         public void setI(int i) {
-             this.i = i;
- Â Â Â Â Â Â Â Â }
- Â Â Â Â }
- Â Â Â Â //Â resource2
-     private class resource2 {
-         private int i = 20;
-         public int getI() {
-             return i;
- Â Â Â Â Â Â Â Â }
-         public void setI(int i) {
-             this.i = i;
- Â Â Â Â Â Â Â Â }
- Â Â Â Â }
- }
Output:
In block 1 In block 2
In the above code, class DeadlockSolved solves the deadlock kind of situation. It will help in avoiding deadlocks, and if encountered, in resolving them.
How to Avoid Deadlock in Java?
Deadlocks cannot be completely resolved. But we can avoid them by following basic rules mentioned below:
- Avoid Nested Locks: We must avoid giving locks to multiple threads, this is the main reason for a deadlock condition. It normally happens when you give locks to multiple threads.
- Avoid Unnecessary Locks: The locks should be given to the important threads. Giving locks to the unnecessary threads that cause the deadlock condition.
- Using Thread Join: A deadlock usually happens when one thread is waiting for the other to finish. In this case, we can use join with a maximum time that a thread will take.
Learn to code from industry experts! Enroll here
Java Deadlock Example and Solution
As configurations are shared resources and when accessing via Threads, there is always chance of writing incorrect code which can cause in deadlock situation.
1. Deadlock
In Java, a deadlock is a situation where minimum two threads are holding the lock on some different resource, and both are waiting for other’s resource to complete its task. And, none is able to leave the lock on the resource it is holding.
package thread; public class ResolveDeadLockTest {   public static void main(String[] args) {     ResolveDeadLockTest test = new ResolveDeadLockTest();     final A a = test. new A();     final B b = test. new B();     // Thread-1     Runnable block1 = new Runnable() {       public void run() {         synchronized (a) {           try {             // Adding delay so that both threads can start trying to             // lock resources             Thread.sleep( 100 );           } catch (InterruptedException e) {             e.printStackTrace();           }           // Thread-1 have A but need B also           synchronized (b) {             System.out.println( "In block 1" );           }         }       }     };     // Thread-2     Runnable block2 = new Runnable() {       public void run() {         synchronized (b) {           // Thread-2 have B but need A also           synchronized (a) {             System.out.println( "In block 2" );           }         }       }     };     new Thread(block1).start();     new Thread(block2).start();   }   // Resource A   private class A {     private int i = 10 ;     public int getI() {       return i;     }     public void setI( int i) {       this .i = i;     }   }   // Resource B   private class B {     private int i = 20 ;     public int getI() {       return i;     }     public void setI( int i) {       this .i = i;     }   } } |
Running above code will result in a deadlock for very obvious reasons (explained above). Now we have to solve this issue.
Grab the opportunity to learn Python with Entri! Click Here
2. How to avoid deadlock
I believe, the solution to any problem lies in identifying the root of the problem. In our case, it is the pattern of accessing the resources A
 and B
, is main issue. So, to solve it, we will simply re-order the statements where the code is accessing shared resources.
     // Thread-1 Runnable block1 = new Runnable() {   public void run() {     synchronized (b) {       try {         // Adding delay so that both threads can start trying to         // lock resources         Thread.sleep( 100 );       } catch (InterruptedException e) {         e.printStackTrace();       }       // Thread-1 have A but need B also       synchronized (a) {         System.out.println( "In block 1" );       }     }   } }; // Thread-2 Runnable block2 = new Runnable() {   public void run() {     synchronized (b) {       // Thread-2 have B but need A also       synchronized (a) {         System.out.println( "In block 2" );       }     }   } }; |