Reason why suspend() and resume() methods are deprecated and Deadlock prone in java


Suspend() method is deadlock prone. If the target thread holds a lock on object when it is suspended, no thread can lock this object until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, it results in deadlock formation.
These deadlocks are generally called Frozen processes.


Suspend() method puts thread from running to waiting state. And thread can go from waiting to runnable state only when resume() method is called on thread. It is deprecated method.

Resume() method is only used with suspend() method that’s why it’s also deprecated method.


Let’s create a program to understand how improper use of suspend() and resume() methods lead us to Deadlock >

We will create Thread-1 and then it will obtain lock on String.class and then call suspend() method on this thread. Calling suspend() will put thread in waiting state.
Than Thread-2 will try to acquire lock on String.class but lock is holded by Thread-1 and deadlock will be formed (as resume wasn’t called on Thread-1).

/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class SuspendResumeDeadlock {
   public static void main(String[] args) throws InterruptedException {
  
          final Thread thread1=new Thread("Thread-1"){
                 public void run() {
                       System.out.println(Thread.currentThread().getName()+" has started.");
                       synchronized (String.class) {
                              System.out.println(Thread.currentThread().getName()+" "
                                            + " has obtained lock on String.class "
                                            + " & suspended...");
                             
                              /*suspend the thread, now this thread will release lock on
                              * String.class (by exiting synchronized block) only when
                              * resume() method
                              * is called on this thread, thread will go in waiting state.
                              */
                              Thread.currentThread().suspend();
                             
                              System.out.println(Thread.currentThread().getName()+" "
                                            + " has released lock on String.class");
                       }
                       System.out.println(Thread.currentThread().getName()+" has ENDED.");
                 }
          };
          thread1.start();
         
          Thread.sleep(2000); //This delay ensures Thread-2 after Thread-1
         
          Thread thread2=new Thread("Thread-2"){
                 public void run() {
                       System.out.println(Thread.currentThread().getName()+" has started.");
                      
                      
                       //Thread-1 is not going to release lock on String.class
                       //until resume() method is not called.
                      
                       /*for acquiring lock on String.class thread-1 must have
                       * released lock on String.class,
                       * if lock is not released, Thread-2 will keep on waiting
                       * for Thread-1 to release lock on String.class  &
                       * deadlock will be formed.
                       */
                      
                       System.out.println(Thread.currentThread().getName()+
                                     " is trying to obtain lock on String.class");  
                       synchronized (String.class) {
                              System.out.println(Thread.currentThread().getName()+
                                            " has obtained lock on String.class");
                              System.out.println(Thread.currentThread().getName()+
                                            " has released lock on String.class");
                       }
                       System.out.println(Thread.currentThread().getName()+" has ENDED.");
                 }
          };
          thread2.start();
   }
  
}
/*OUTPUT
Thread-1 has started.
Thread-1 has obtained lock on String.class  & suspended...
Thread-2 has started.
Thread-2 is trying to obtain lock on String.class
*/
One crucial thing to note down in output was " has ENDED" was never printed in output, because of deadlock Thread-1 & Thread-2 never ended.




Let’s solve deadlock which was formed because of improper use of suspend() and resume() methods >

We will create Thread-1 and then it will obtain lock on String.class and then call suspend() method on this thread. Calling suspend() will put thread in waiting state. Than resume() method will be called on Thread-1 (which will bring thread from waiting to runnable state and later to running state) and Thread-1 will complete its execution and release lock on String.class . Than Thread-2 will try to acquire lock on String.class and lock is available. Thread-2 will also complete its execution successfully.

/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class SuspendResumeDeadlockSolve {
   public static void main(String[] args) throws InterruptedException {
  
          final Thread thread1=new Thread("Thread-1"){
                 public void run() {
                       System.out.println(Thread.currentThread().getName()+" has started.");
                       synchronized (String.class) {
                              System.out.println(Thread.currentThread().getName()+
                                            " has obtained lock on String.class "
                                            + " & suspended...");
                             
                              /*suspend the thread, now this thread will release
                              * lock on
                              * String.class (by exiting synchronized block) only
                              * when resume() method
                              * is called on this thread, thread will go in waiting state.
                              */
                              Thread.currentThread().suspend();
                             
                              System.out.println(Thread.currentThread().getName()+
                                            " has released lock on String.class");
                       }
                       System.out.println(Thread.currentThread().getName()+" has ENDED.");
                 }
  
          };
          thread1.start();
         
          Thread.sleep(2000); //This delay ensures Thread-2 after Thread-1
         
          Thread thread2=new Thread("Thread-2"){
                 public void run() {
                       System.out.println(Thread.currentThread().getName()+" has started.");
                      
                      
                       //Thread-1 is not going to release lock on String.class
                       //until resume() method is not called.
                       //resume the thread.
                       thread1.resume();
                       System.out.println(thread1.getName()+" has been resumed...");
                      
                      
                       /*for acquiring lock on String.class thread-1 must
                       * have released lock on String.class,
                       * if lock is not released, Thread-2 will keep on waiting
                       * for Thread-1 to release lock on String.class  &
                       * deadlock will be formed.
                       */
                   
                       System.out.println(Thread.currentThread().getName()+
                                     " is trying to obtain lock on String.class");  
                       synchronized (String.class) {
                              System.out.println(Thread.currentThread().getName()+
                                            " has obtained lock on String.class");
                              System.out.println(Thread.currentThread().getName()+
                                            " has released lock on String.class");
                       }
                       System.out.println(Thread.currentThread().getName()+" has ENDED.");
                 }
  
          };
          thread2.start();
   }
  
}
/*OUTPUT
Thread-1 has started.
Thread-1 has obtained lock on String.class  & suspended...
Thread-2 has started.
Thread-1 has been resumed...
Thread-2 is trying to obtain lock on String.class
Thread-1 has released lock on String.class
Thread-2 has obtained lock on String.class
Thread-2 has released lock on String.class
Thread-2 has ENDED.
Thread-1 has ENDED.
*/
One crucial thing to note down in output was " has ENDED" was printed in output, because Thread-1 & Thread-2 completed successfully.




RELATED LINKS>



Important Thread methods (salient features, usage with programs)>

Join() method - ensure all threads that started from main must end in order in which they started and also main should end in last. Types of join() method-10 salient features of join

Sleep() method in threads - 10 key features with programs

Yield() method in threads - 8 key features with programs

Wait() and notify() methods- Definition, 8 key features, solving consumer producer problem with & without these methods and consequences of not using wait() and notify() methods.

Daemon threads - 12 salient features of Daemon Thread

2 alternate ways to stop thread, as stop() method is deprecated

Using Suspend and resume method in threads



Differences between important thread methods >

Difference between wait() and sleep() method in threads

Differences and similarities between yield() and sleep() in threads

Difference between notify() and notifyAll() methods, with program

Difference between wait() and wait(long timeout) -What will be Thread states



Interviews >

THREADS - Top 75 interview questions and answers (detailed explanation with programs) Set-1 >  Q1- Q54

THREADS - Top 75 interview questions and answers, important interview OUTPUT questions and answers, Set-2 > Q55- Q76





No comments:

Post a Comment