-3

I was trying to create A Java dead lock program . I know in real time we wont be creating any dead lock in thread. Unfortunately I have been asked in one of the interview to writing a "Deadlock program using two threads". So here it is

package Thread.DeadLock;

public class deadLock2 {

  static ThreadSample1 t1 = new ThreadSample1();
  static ThreadSample2 t2 = new ThreadSample2();

  public static void main(String args[]) {

    t1.start();
    t2.start();
  }

  public static class ThreadSample1 extends Thread {
    public void run() {
      System.out.println("In first run method");
      try {
        System.out.println("Holding lock in first one");
        synchronized (t1) {
          System.out.println("t1 going to wait for t2");

          t1.wait();
          System.out.println("t1 finished for waiting");
        }
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }

  public static class ThreadSample2 extends Thread {
    public void run() {
      System.out.println("In second run method");
      try {
        System.out.println("Holding lock for second one");
        synchronized (t2) {
          System.out.println("t2 going to wait for t1");

          t2.wait();
          System.out.println("t2 finished for waiting");
        }
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}

I can see the program is getting stuck. I am assuming that it in deadlock situation. t1.start() waits for t2 to finish its task and t2.start() waits for t1 to finish its task. Now while I try to remove the deadlock by notifying the waiting thread using using t1.notify() I get IllegalMonitorStateException. Can somebody tell in this situation how to remove the deadlock without causing any situation.

Rashmi
  • 271
  • 1
  • 2
  • 11
  • Why are you referencing t1 and t2 variables? You shouldn't explicitly handle Threads by using references.. – mlewandowski Mar 07 '16 at 09:09
  • Does your code exhibit the [4 necessary and sufficient requirements for deadlock](http://nob.cs.ucdavis.edu/classes/ecs150-1999-02/dl-cond.html)? (I think it exhibits just the first 3 as listed here). – Andy Turner Mar 07 '16 at 09:13

3 Answers3

2

First, this is not deadlock. As you correctly described, deadlock is usually situation when there is circular dependency between two or more threads waiting for resources that is held by other thread.

Here, each thread independently waits for notification on itself which is actually not delivered by anybody else in the system. Even if there is no deadlock.

Secondly, IllegalMonitorStateException means that you try to notify/wait on monitor which is not held by the thread. In other words, there is no synchronized prior to notify/wait.

Third, to achieve real deadlock you can do something like this:

synchronized(t1) {
    synchronized(t2) {
        t2.wait();
    }
    t1.notify();
}

and vice versa for the other thread.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
0

You can not call notify()/notifyAll() unless the current thread owns that object's monitor. To do that, you must synchronize on it, as you did with wait()

The Javadocs for wait() mention this:

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

Throws:

IllegalMonitorStateException – if the current thread is not the owner of this object's monitor.

And from notify():

A thread becomes the owner of the object's monitor in one of three ways:

  • By executing a synchronized instance method of that object.
  • By executing the body of a synchronized statement that synchronizes on the object.
  • For objects of type Class, by executing a synchronized static method of that class.

See this answer:

Java Wait and Notify: IllegalMonitorStateException

Community
  • 1
  • 1
0
package pck.pramod.geekforgeeks;

public class ThreadDeadlock {

    public static Object Lock1 = new Object();
    public static Object Lock2 = new Object();

    public static void main(String args[]) {
        System.out.println(Lock1.toString() + " " + Lock2.toString());
        ThreadDemo1 T1 = new ThreadDemo1(Lock1, Lock2, "T1");
        ThreadDemo1 T2 = new ThreadDemo1(Lock2, Lock1, "T2");
        T1.start();
        T2.start();
    }

}

class ThreadDemo1 extends Thread {
    Object lock1;
    Object lock2;
    String name;

    public ThreadDemo1(Object lock1, Object lock2, String name) {
        this.lock1 = lock1;
        this.lock2 = lock2;
        this.name = name;
    }

    public void run() {
        synchronized (lock1) {
            System.out.println(name + " Holding lock ..." + lock1.toString());

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
            System.out.println(name + " Waiting for lock ..." + lock2.toString());

            synchronized (lock2) {
                System.out.println(name + " Holding lock ..." + lock1.toString() + " " + lock2.toString());
            }
        }
    }
}

  • While this might answer the question, you should [edit] your answer to include an explanation of how your code answers your question, to provide more context to future readers. A code block by itself is not immediately useful to those who might come across the same issue later on. – Hoppeduppeanut Jun 19 '19 at 07:15