ajay
ajay

Reputation: 13

is this a thread deadlock

I wanted to intentionally do/test java thread deadlock state so I made a following sample code:

public class TestDeadLock extends Thread{
    private Integer a=new Integer(9);
    public void run(){

        if(Thread.currentThread().getName().equals("t1")){
            XXXX();
        }
        else{
            ZZZZ();
        }
    }

    public void XXXX(){
        System.out.println("inside XXXX");
        synchronized(a){
            a++;
            ZZZZ();
        }
        System.out.println("xxxxxxxxxxxxxxxxxxx");
        //ZZZZ();
    }

    public synchronized void ZZZZ(){
        System.out.println("inside ZZZZ");
        synchronized(a){
            a--;
            XXXX();
        }
        System.out.println("zzzzzzzzzzzzzzzzzzzzz");
    }

    public static void main(String[] args) throws InterruptedException {
        TestDeadLock tdl=new TestDeadLock();
        Thread t1=new Thread(tdl);
        Thread t2=new Thread(tdl);
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();

        Thread.sleep(1000);
        System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="+tdl.a);
    }
}

The output came out to be like :

inside XXXX

inside ZZZZ

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=10

output is NOT exiting.

I wanted to know, was it due to threads reached Dead Lock state? Is it a right example to experience Dead Lock. Suggest or correct me if I am wrong.

Upvotes: 1

Views: 178

Answers (4)

Ouney
Ouney

Reputation: 1194

Example given by Jase Pellerin is a good example of dead lock but it has one mistake (Sorry Jase Pellerin , i am sure you did it unintetionally) . Here, both methods are trying to get hold of Lock1 first and then Lock2. I think it should be other way around.

Thread1{

synchronized (Lock1) {

synchronized (Lock2) {}

}
}

Thread2{

 synchronized (Lock2) {

 synchronized (Lock1) {}

 }
 }

Upvotes: -1

Edward L.
Edward L.

Reputation: 564

Your ZZZZ() method contains a call to XXXX() method and vice-versa. Thus, you have created a never-ending chain of calls that goes: ZZZZ() -> XXXX() -> ZZZZ() -> XXXX() -> etc.

Eventually, your stack will grow too large from all the nested method calls that get pushed onto the stack. Hence, the exceptions that you are getting.

Upvotes: 3

Jase Pellerin
Jase Pellerin

Reputation: 397

Try this example:

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();

   public static void main(String args[]) {

      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }

   private static class ThreadDemo1 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }
   private static class ThreadDemo2 extends Thread {
      public void run() {
         synchronized (Lock2) {
            System.out.println("Thread 2: Holding lock 2...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 1...");
            synchronized (Lock1) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

This accurately shows threads reaching deadlock.

Here is the solution:

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();

   public static void main(String args[]) {

      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }

   private static class ThreadDemo1 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }
   private static class ThreadDemo2 extends Thread {
      public void run() {
         synchronized (Lock1) {
            System.out.println("Thread 2: Holding lock 1...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 2...");
            synchronized (Lock2) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

Source: http://www.tutorialspoint.com/java/java_thread_deadlock.htm

Upvotes: 0

nrainer
nrainer

Reputation: 2623

No, you are not experiencing a dead lock. You are encountering a StackOverflowError because you are running into an infinite loop.

Note that your method

public synchronized void ZZZZ() {
  System.out.println("inside ZZZZ");

    XXXX(); // run-time exception
}

is equivalent to

public void ZZZZ() {
  synchronized(this) {
    System.out.println("inside ZZZZ");

      XXXX(); // run-time exception
  }
}

You are not causing a dead lock because you are working on two different instances. Thread 1 locks t1, thread 2 locks t2.

Upvotes: 6

Related Questions