What is deadlock?

A deadlock is a situation in which two or more processes are waiting indefinitely for an event to happen, and that event can only be caused by one of these waiting processes, but none of these processes can cause that event because they are in a wait state. 

In a multithreaded environment, because multiple threads are running concurrently, the deadlock is possible. Several situations can give rise to a deadlock. This post discusses a very simple situation, coded in below Listing, in which two threads, t1 and t2, are sharing the resources resourceA and resourceB. These threads access these resources in reverse order (lines 5 and 6). Thread t1 seeks a lock on obj1 and then on obj2, while thread t2 seeks a lock on obj2 and then on obj1 (lines 5, 6, and 20 through 28). Although the lock access code that is executed for each thread is the same (lines 20 through 28), resource A means obj1 for thread t1 and obj2 for thread t2, and resourceB means obj2 for thread t1 and obj1 for thread t2 due to lines 5, 6, 16, and 17.



DeadLockTest.java

1. public class DeadLockTest {
2.      public static void main(String[] args) {
3.           Object obj1 = "objectA";
4.           Object obj2 = "objectB";
5.           DeadLock t1 = new DeadLock(obj1, obj2);
6.           DeadLock t2 = new DeadLock(obj2, obj1);
7.           t1.start();
8.            t2.start();
9.            System.out.println("The threads have been started");
10.    }
11. }

12. class DeadLock extends Thread {
13.     private Object resourceA;
14.     private Object resourceB;
15.   public DeadLock(Object a, Object b){
16.        resourceA = a;
17.        resourceB = b;
18. }

19.   public void run() {
20.      while (true) {
21.      System.out.println("The thread " + 
                        Thread.currentThread().getName()
                         + " waiting for a lock on " + resourceA);
22.      synchronized (resourceA){
23.      System.out.println("The thread " + Thread.currentThread().getName()
                             + " received a lock on " + resourceA);
24.       System.out.println("The thread " + Thread.currentThread().getName()
                             + " waiting for a lock on " + resourceB);
25.        synchronized (resourceB){
26.        System.out.println("The thread " +
                    Thread.currentThread().getName() + " received a lock on " +
                    resourceB);

27.            try{
28.              Thread.sleep(500);
29.           }catch (Exception e){}
30.        }
31.     }
32.    }
33.   }
34. }

When you execute this code, the output is not deterministic. However, it is easy to see from lines 20 through 30 that eventually a deadlock will happen because t1 will not release a lock on obj1 until it receives a lock on obj2, whereas t2 will not release a lock on obj2 until it receives a lock on obj1. Following is one of the outputs that you may receive:

     The threads have been started
    The thread Thread-0 waiting for a lock on objectA
    The thread Thread-0 received a lock on objectA
    The thread Thread-1 waiting for a lock on objectB
    The thread Thread-0 waiting for a lock on objectB
    The thread Thread-1 received a lock on objectB
    The thread Thread-1 waiting for a lock on objectA



Reference(s): SCJP Exam for J2SE 5

No comments:

Post a Comment