title: How to resolve this deadlock?
body: <p>I have added comments in code to explain from where deadlock is occurring.
  Basically, There are two threads. Each thread acquires lock on an <code>Manager</code> object and then go for acquiring lock on static resource, which is a map of all the <code>Manager</code> objects in the application.Both thread calls <code>get()</code> on map.
  <code>Manager</code> class has overridden <code>equals()</code> method. <code>equals()</code> further calls some synchronized method of <code>Manager</code> class. So a <code>get()</code> on map will need object level lock on each object in the map one by one until key matches because equals is overridden.
  I can only change the code in sub classes(<code>Sub1</code> and <code>Sub2</code>) and avoid the deadlock, as I don't have access to other classes.</p>
  
  <p>Edit: I don't have access to syncMap. The code in 'synchronized' block executes in third party code whose API I call to.</p>
  
  <p>Can I avoid this by acquiring lock in <code>finally</code> on <code>Manager</code>, rather than before try block ?!</p>
  
  <pre><code>    public class Parent{
          protected Manager manager;
      }
  
      public class Global{
          private static final Map syncMap = Collections.synchronizedMap(new HashMap());
          //syncMap contains all the objects of Manager in the application
      }
  
      class Manager{
  
  
          public boolean equals(Object o){
  
              Manager obj = (Manager)o;
              return obj.getURL().equals(getURL());
          }
  
          public final synchronized String getURL(){
              return msettings.getDBURL(); //msettings is a global variable
          }
  
  
      }
  
  
      //Thread-1 is executing someMethod() of this class
  
      class Sub1 extends Parent{
          Global global;
          //consider manager and Global object are not null
          public void someMethod()
          {
              synchronized(manager){// Thread-1 succesfully takes object level lock on a manager object, say Manager01
                  try{
                      global.syncMap.get(manager);
                      // Thread-1 Succesfully takes class level lock on syncMap
                      //  get() calls equals() for each object in syncMap. 
                      //equals() need object lock on each Manager Object in map as it further calls synchronized getURL()
                      // But on one manager Object(Manager02) Thread-2 has already acquired lock and is waiting for lock on syncMap which this thread-1 holds
  
                  }
                  finally{
                      manager.releaseConnection();
                  }
  
              }
          }
      }
  
      //Thread-2 is executing otherMethod() of this class
      class Sub2 extends Parent{ 
          public void otherMethod()
          {
              synchronized(manager){// this takes a lock on manager(Manager02)
                  try{
                      global.syncMap.get(manager);
                      // this is blocked as syncMap is aquired by thread-1
  
  
                  }
                  finally{
                      manager.releaseConnection();
                  }
  
              }
          } 
      }
  </code></pre>