Saturday 4 November 2017

Deadlock in Java multithreading - Program to generate the Deadlock and to avoid Deadlock in Java

          This is very important question for interview perspective.  First understand, what is deadlock and how to generate the deadlock, i.e write a code to generate deadlock. In this post we will learn these and also to learn how to solve the deadlock.

         The synchronized keyword is used to make the class or method safe which means only one thread can have a lock of synchronized method and use it. Other threads have to wait till the lock releases and anyone of them acquire that lock. It is important to use if our program is running in multi-threaded environment where two or more threads execute simultaneously.


What is a Deadlock ?


          In Java multi-threading, Deadlock is a situation where minimum two threads are holding lock on different resource and both are waiting for others resource to complete it's task. And both threads can hold lock forever and none of them complete it's task.
         
Below is the simple deadlock example,

Deadlock in Java
Deadlock example


















Program to generate the Deadlock :


package com.pr;

public class DeadlockEx {
 
      public static Object object1 = new Object();
      public static Object object2 = new Object();
      public static void main(String[] args) {
              ThreadEx1 thread1 = new ThreadEx1();
              ThreadEx2 thread2 = new ThreadEx2();
              thread1.start();
              thread2.start();
      }
 
      private static class ThreadEx1 extends Thread {
             public void run() {
                    synchronized(object1) {
                         System.out.println("ThreadEx1 : holding lock on object1");
                         try {
                                Thread.sleep(1000);
                          } catch (InterruptedException e) {
                             // TODO Auto-generated catch block
                          }
                          System.out.println("ThreadEx1 : waitig to release lock on object2");
                          synchronized(object2) {
                                  System.out.println("ThreadEx1: both object1 and object2 in lock");
                          }
                   }
            }
      }
 
      private static class ThreadEx2 extends Thread {
              public void run() {
                     synchronized(object2) {
                             System.out.println("ThreadEx2 : holding lock on object2");
                             try {
                                   Thread.sleep(1000);
                              } catch (InterruptedException e) {
                                    // TODO Auto-generated catch block
                              }
                              System.out.println("ThreadEx2 : waitig to release lock on object1");
                              synchronized(object1) {
                                    System.out.println("ThreadEx2: both object1 and object2 in lock");
                              }
                     }
              }
      }

}
   
Output:- ThreadEx1 : holding lock on object1
                ThreadEx2 : holding lock on object2
                ThreadEx2 : waitig to release lock on object1
                ThreadEx1 : waitig to release lock on object2

The above program will hang forever because neither of thread to proceed to execute the task and not to release the lock .

Deadlock Solution:

  
          In above code,  just change the order of the lock and check the output. It can solve the deadlock problem. This code is simple deadlock problem and solution but in real time application it's complicated to find out deadlock and also complicated to fix the deadlock issue.
     
          The deadlock solution program as below,

package com.pr;

public class DeadlockEx {
 
      public static Object object1 = new Object();
      public static Object object2 = new Object();
      public static void main(String[] args) {
              ThreadEx1 thread1 = new ThreadEx1();
              ThreadEx2 thread2 = new ThreadEx2();
              thread1.start();
              thread2.start();
      }
 
      private static class ThreadEx1 extends Thread {
             public void run() {
                    synchronized(object1) {
                             System.out.println("ThreadEx1 : holding lock on object1");
                             try {
                                   Thread.sleep(1000);
                              } catch (InterruptedException e) {
                                  // TODO Auto-generated catch block
                              }
                              System.out.println("ThreadEx1 : waiting to release lock on object2");
                              synchronized(object2) {
                                     System.out.println("ThreadEx1: both object1 and object2 in lock");
                              }
                      }
             }
      }
 
      private static class ThreadEx2 extends Thread {
             public void run() {
                   synchronized(object1) {
                         System.out.println("ThreadEx2 : holding lock on object1");
                         try {
                                Thread.sleep(1000);
                         } catch (InterruptedException e) {
                               // TODO Auto-generated catch block
                         }
                         System.out.println("ThreadEx2 : waiting to release lock on object2");
                         synchronized(object2) {
                                System.out.println("ThreadEx2: both object1 and object2 in lock");
                         }
                   }
             }
      }

}

Output :- ThreadEx1 : holding lock on object1
                 ThreadEx1 : waiting to release lock on object2
                 ThreadEx1: both object1 and object2 in lock
                 ThreadEx2 : holding lock on object1
                 ThreadEx2 : waiting to release lock on object2
                 ThreadEx2: both object1 and object2 in lock



Important Points to Avoid Deadlock:

  1.   Lock a specific member variables of class rather than  locking a whole class.
  2.   Use Thread join method, possible try to use join method. Advantage of join is it will start and end sequentially.

            VisualVM and jstack these are the tools to detect the deadlock in java. For more details about VisualVM and jstack refer Java thread dump.


Related Posts: 

No comments:

Post a Comment