Dynamic Lock-ordering Deadlock Solution

We have seen a dynamic lock ordering deadlock example previously.

One solution, according to suggestion from Java Concurrency in Practice, is to make use of System.identityHashCode to order objects. We can change the above program by introducing a method1 wrapper class that will send the objects in the correct order after checking its System.identityHashCode value. In a rare case, the values of System.identityHashCode may be same for both objects, and in this case we will use additional synchronization to make sure only one thread will call method1 and hence the order does not matter.

 

Dynamic lock-ordering solution program

package deadlock;

 

public class DynamicLockOrderingSolution {

  final static Object lockObject1 = new Object();

  final static Object lockObject2 = new Object();

  final static Object controlLock = new Object();

 

  public static void method1Wrapper(Object obj1, Object obj2) {

    int obj1Hash = System.identityHashCode(obj1);

    int obj2Hash = System.identityHashCode(obj2);

 

    if (obj1Hash < obj2Hash) {

      method1(obj1, obj2);

    } else if (obj1Hash > obj2Hash) {

      method1(obj2, obj1);

    } else {

      synchronized (controlLock) {

        method1(obj1, obj2);

      }

    }

  }

 

  public static void method1(Object obj1, Object obj2) {

    synchronized (obj1) { // Locking on obj1

      System.out.println(Thread.currentThread().getName()

          + ": Got obj1. Trying for obj2");

      try {

        Thread.sleep(500);

      } catch (InterruptedException e) {

        e.printStackTrace();

      }

 

      synchronized (obj2) // Locking on obj2

      {

        System.out.println(Thread.currentThread().getName()

            + ": Got obj2.");

      }

    }

  }

 

  public static void main(String[] args) {

    Thread t1 = new Thread() {

      public void run() {

        DynamicLockOrderingSolution.method1Wrapper(lockObject1, lockObject2);

      }

    };

    t1.setName("Thread A");

    t1.start();

 

    Thread t2 = new Thread() {

      public void run() {

        DynamicLockOrderingSolution.method1Wrapper(lockObject2, lockObject1);

      }

    };

    t2.setName("Thread B");

    t2.start();

  }

}

Just copy paste, execute, make changes and try to understand.

References and notes: 

Java Concurrency in Practice by Brian Goetz, David Holmes, DOug Lea, Tim Peierls, Joshua Bloch and Joseph Bowbeer. 

http://javajee.com/deadlock-in-operating-systems

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!