Thursday, August 12, 2010

Java Deadlocking Example

Sometimes you need to test a piece of code that deals with deadlocking threads in Java. Below is a small program that deadlocks as soon as it starts.

A class that holds names of the threads


public class Constants {
  public static final String THREADNAME_1 = "Threadname 1";
  public static final String THREADNAME_2 = "Threadname 2"; 
}

The deadlocking class


import  java.util.concurrent.locks.*;

public class ThreadTestDeadlockingLock {

  Lock lock1 = new ReentrantLock();
  Lock lock2 = new ReentrantLock();

  Thread tr1 = new Thread(new runnableClass(), Constants.THREADNAME_1); 
  Thread tr2 = new Thread(new runnableClass(), Constants.THREADNAME_2);
 
  public ThreadTestDeadlockingLock(){
  }
 
  public static void main(String[] argc){

     ThreadTestDeadlockingLock threadtest = new ThreadTestDeadlockingLock();
  
     threadtest.tr1.start();
     threadtest.tr2.start();
  
   }

   /*
    * Runnable class definition
   */
   class runnableClass implements Runnable {
  
     public runnableClass(){
     }

     public void getLock1Lock2(){
        try{
           lock1.lock();
           System.out.println("Thread "+
                Thread.currentThread().getName() + " Locked 1");
           Thread.sleep(10);
           lock2.lock();
           System.out.println("Thread " +
                Thread.currentThread().getName() + " Locked 2");
           /*
            * Do work, do not release locks
            */
           Thread.sleep(1000);

        }
        catch(Exception ex){
           System.out.println("Exception in getLock1Lock2 " + 
                ex.toString());
        }
        finally {
            lock2.unlock();
            lock1.unlock();
        }
  }

  public void getLock2Lock1(){
      try{
          lock2.lock();
          System.out.println("Thread "+
               Thread.currentThread().getName() + " Locked 2");
          Thread.sleep(10);
          lock1.lock();
          System.out.println("Thread "+
               Thread.currentThread().getName() + " Locked 1");
          /*
           * Do work, do not release locks
           */
          Thread.sleep(1000);
       }
       catch (Exception ex){
         System.out.println("Exception in getLock2Lock1()" + ex.toString());
       }
       finally {
         lock1.unlock();
         lock2.unlock();
       }
  }

  public void run(){
  
     for(int i=0; i<100; i++){
         if(Constants.THREADNAME_1.equals(Thread.currentThread().getName())){
              getLock1Lock2();
         }
         else {
              getLock2Lock1();
         }     
      }   
  }
 } // End of internal class
}