user_vs
user_vs

Reputation: 1033

java code for deadlock situation?

here is the code

public class TestDeadlockExample1 {
     public static void main(String[] args) {  
            final String resource1 = "xyz";  
            final String resource2 = "pqr";  
            // t1 tries to lock resource1 then resource2  
            Thread t1 = new Thread() {  
              public void run() {  
                  synchronized (resource1) {  
                   System.out.println("Thread 1: locked resource 1");  

                   try { Thread.sleep(10000);} catch (Exception e) {}  

                   synchronized (resource2) {  
                    System.out.println("Thread 1: locked resource 2");  
                   }  
                 }  
              }  
            };  

            // t2 tries to lock resource2 then resource1  
            Thread t2 = new Thread() {  
              public void run() {  
                synchronized (resource2) {  
                  System.out.println("Thread 2: locked resource 2");  

                  try { Thread.sleep(10000);} catch (Exception e) {}  

                  synchronized (resource1) {  
                    System.out.println("Thread 2: locked resource 1");  
                  }  
                }  
              }  
            };  


            t1.start();  
            t2.start();  
            System.out.println("completed");
          }  
}


here 

 t1.start();  
 t2.start();  
 System.out.println("completed");

here

in this t1.start() and t2.start() are written in sequential order, so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes, if this is correct, how this becomes a deadlock situation..i want to know the execution of these threads

Upvotes: 1

Views: 301

Answers (6)

Rajesh
Rajesh

Reputation: 384

The order of thread execution is not defined.

There is a high risk for your program to go to deadlock. But you can slightly change the order of lock in the second thread to avoid deadlock. I've modified and given below. Again this depends on the logic you are going to write.

Thread t2 = new Thread() {  
  public void run() {  
    synchronized (resource1) {  
      System.out.println("Thread 2: locked resource 2");  

      try { Thread.sleep(10000);} catch (Exception e) {}  
      System.out.println("Thread 2: Waiting for resource 1...");
      synchronized (resource2) {  
        System.out.println("Thread 2: locked resource 1 and 2");  
      }  
    }  
  }  
};

Upvotes: 0

APD
APD

Reputation: 1519

"so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes"

Simply because the threads t1 and t2 are spawned sequentially, does not imply that they execute sequentially. Threads are used for parallel execution of units of work.

Due to the sleep method calls in your code, it will deadlock because

  1. t1 acquires R1 or t2 acquires t2. The order is indeterminate

  2. Both threads sleep for 10 seconds after acquiring their respective resource, so we can be say with high degree of certainty in this example that both threads have acquired the resources at some point during the sleep period of the other.

  3. When t1 or t2 wake up and try to acquire the second resource, which is already held by the respective threads sibling it will block. Both threads will block attempting to acquire the resource held by the other.

This scenario only occurs because the threads are executing in parallel, not sequentially.

Please see http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

Upvotes: 0

vbezhenar
vbezhenar

Reputation: 12316

When you launch your java program, JRE spawns main thread and that main thread executes your main method.

When you call t1.start(), new thread spawns and executes first anonymous class's run method. From this point there are 2 threads executing simultaneously in your program: "main thread" and "thread 1".

When you call t2.start(), another thread spawns and executes second anonymous class's run method. From this point there are 3 threads executing simultaneously in your program: "main thread", "thread 1", "thread 2".

The order in which threads are executing is not defined. It could be anything. Generally they are executing simultaneously.

Your "thread 1" and "thread 2" acquire locks on resource1 and resource2 correspondingly and sleep for 10 seconds. While that happens, your "main" thread finishes its execution. But there are 2 more threads in your program, so while main method finished, program is not finished yet.

After sleeping your "thread 1" and "thread 2" trying to acquire locks on resource 2 and resource 1, but those locks are already acquired so they will wait until lock holder will release it. Lock holder will never release it, as it waits for other resource so this program will never stop. That's classic deadlock situation.

Upvotes: 1

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

sleep() guarantees that both t1 and t2 acquire their first lock before they proceed to their second lock. No matter which thread runs first.

Upvotes: 0

TheLostMind
TheLostMind

Reputation: 36304

in this t1.start() and t2.start() are written in sequential order, so my doubt is that both the thread starts at the same or not or t1 starts, executes then comes to t2 and executes

A call to start() doesn't ensure that a Thread starts immediately. A native call is made via start0() which inturn calls the OS to fork a thread. So, basically, thread2 can start before thread1. You have no control over which thread starts first.

how this becomes a deadlock situation

There is a probability of deadlock here because t1 might get lock on resource1 and t2 might get lock on resource2 at the same time. Now, both threads want the resource held by the other thread. Hence you have a deadlock.

So as a standard practice, both t1 and t2 should acquire lock in the same sequence.

Upvotes: 0

EpicPandaForce
EpicPandaForce

Reputation: 81539

I have learned that to prevent deadlocks, you need to make the synchronized block be consistently the same.

          public void run() {  
              synchronized (resource1) {  
              synchronized (resource2) {  
               System.out.println("Thread 1: locked resource 1");  
               System.out.println("Thread 1: locked resource 2");  
               try { Thread.sleep(10000);} catch (Exception e) {}  
               }  
             }  
          }  

and

        Thread t2 = new Thread() {  
          public void run() {  
            synchronized (resource1) {  
            synchronized (resource2) {  
              System.out.println("Thread 2: locked resource 2");  
              System.out.println("Thread 2: locked resource 1");  
              try { Thread.sleep(10000);} catch (Exception e) {}  
              }  
            }  
          }  
        };  

Upvotes: 0

Related Questions