title: How to ensure locking-order to avoid deadlock?
body: <p>Assume there are two objects of the following Account class - account1 and account2. And there are two threads T1 and T2. </p>
  
  <p>T1 is transferring amount 100 from account1 to account2 as follows:</p>
  
  <pre><code>account1.transfer(account2, 100);
  </code></pre>
  
  <p>Similarly, T2 is transferring amount 50 from account2 to account1:</p>
  
  <pre><code>account2.transfer(account1, 50);
  </code></pre>
  
  <p>The transfer() method is obviously prone to deadlock as two threads T1 and T2 would be trying to acquire lock in the reverse order. (Thread T1 will try acquiring lock on account1 first and then account2. Whereas thread T2 will try acquiring lock on account2 and then on account1.)</p>
  
  <p>What is the best way (in this case) to ensure locking-order to be guaranteed always?</p>
  
  <pre><code>public class Account {
      private float balance;
  
      public class Account() {
          balance = 5000f;
      }
  
      private void credit(float amt) {
          balance += amt;
      }
  
      // To exclude noise assume the balance will never be negative
      private void debit(float amt) {
          balance -= amt;
      }
  
      // Deadlock prone as the locking order is not guaranteed
      public void transfer(Account acc2, float amt) {
          synchronized(this) {
              synchronized(acc2) {
                  acc2.debit(amt);
                  this.credit(amt);
              }
          }
      }
  }
  </code></pre>