Evitar el ejemplo de punto muerto

Me pregunto cuáles son las formas alternativas de evitar el interbloqueo en el siguiente ejemplo. El siguiente ejemplo es una cuenta bancaria típica que transfiere un problema de interbloqueo. ¿Cuáles son algunos mejores enfoques para resolverlo en la práctica?

class Account {
     double balance;
     int id;
     public Account(int id, double balance){
          this.balance = balance;
          this.id = id;
     }
     void withdraw(double amount){
          balance -= amount;
     } 
     void deposit(double amount){
          balance += amount;
     }
}
class Main{
     public static void main(String [] args){
           final Account a = new Account(1,1000);
           final Account b = new Account(2,300);
           Thread a = new Thread(){
                 public void run(){
                     transfer(a,b,200);
                 }
           };
           Thread b = new Thread(){
                 public void run(){
                     transfer(b,a,300);
                 }
           };
           a.start();
           b.start();
     }
     public static void transfer(Account from, Account to, double amount){
          synchronized(from){
               synchronized(to){
                    from.withdraw(amount);
                    to.deposit(amount);
               }
          }
     }
}

Me pregunto si resolverá el problema de interbloqueo si separo el bloqueo anidado en mi método de transferencia como el siguiente

 synchronized(from){
      from.withdraw(amount);
 }
 synchronized(to){
      to.deposit(amount);
 }

Respuestas a la pregunta(6)

Su respuesta a la pregunta