Deadlocks in java

Ok, lets start with seeing a simple example of how deadlocks can be created in java. Simple way to achieve this is to try to acquire locks in different order and you will see it happen.

Thread1 – Resource 1, Resource 2
Thread2 – Resource 2, Resource 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Resource1 {
}
 
class Resource2 {
}
 
class DeadlockThread1 implements Runnable {
 
  public void run() {
    while ( true ) {
      synchronized ( Resource1.class ) {
        System.out.println("DeadlockThread1 acquired Resource1");
        synchronized ( Resource2.class ) {
          System.out.println("DeadlockThread1 acquired Resource1 and Resource2");
        }
      }
    }
  } 
 
}
 
class DeadlockThread2 implements Runnable {
 
  public void run() {
    while ( true ) {
      synchronized ( Resource2.class ) {
        System.out.println("DeadlockThread2 acquired Resource2");
        synchronized ( Resource1.class ) {
          System.out.println("DeadlockThread2 acquired Resource2 and Resource1");
        }
      }
    }
  } 
 
}
 
public class Deadlock {
  public static void main(String args[]) {
    Thread dlock1=new Thread(new DeadlockThread1());
    Thread dlock2=new Thread(new DeadlockThread2());
    dlock1.start();
    dlock2.start();
  }
}

Release of Locks:- Ok, say that we acquired resources in the same order, in what order do we release them? In other words, is one of these sequences better than the other?

Sequence 1

  • lock R1
  • lock R2
  • unlock R2
  • unlock R1

Sequence 2

  • lock R1
  • lock R2
  • unlock R1
  • unlock R2

Sequence 1 is recommended. Sequence 2 doesn’t cause issues iff you don’t acquire/unacquire locks between unlock R1 and unlock R2. For e.g.

  • lock R1
  • lock R2
  • unlock R1
  • In the mean time another thread got hold of R1 and is waiting for you to release R2
  • lock R1 <- you are trying to re-lock R1, its a deadlock!