2011-04-06 111 views
0

我正在阅读Java Concurrency in Practice并被卡在这个程序中,作者说它不会导致死锁。但是如果我交换方法参数,那么它会导致死锁。Java线程死锁

Obj1 = hash-code =1 
Obj2 = hash-code =2 

Thread1. transfer(Obj1, Obj2)将获得fromAcct锁并等待toAcct锁定

Thread2.transfer(Obj2, Obj1)将获得toAcct锁并等待fromAcct锁定

所以基本上我们结束-up的死锁。

我的问题是如何在下面的代码中避免死锁。

public class InduceLockOrder { 
    private static final Object tieLock = new Object(); 

    public void transferMoney(final Account fromAcct, 
           final Account toAcct, 
           final DollarAmount amount) 
      throws InsufficientFundsException { 
     class Helper { 
      public void transfer() throws InsufficientFundsException { 
       if (fromAcct.getBalance().compareTo(amount) < 0) 
        throw new InsufficientFundsException(); 
       else { 
        fromAcct.debit(amount); 
        toAcct.credit(amount); 
       } 
      } 
     } 
     int fromHash = System.identityHashCode(fromAcct); 
     int toHash = System.identityHashCode(toAcct); 

     if (fromHash < toHash) { 
      synchronized (fromAcct) { 
       synchronized (toAcct) { 
        new Helper().transfer(); 
       } 
      } 
     } else if (fromHash > toHash) { 
      synchronized (toAcct) { 
       synchronized (fromAcct) { 
        new Helper().transfer(); 
       } 
      } 
     } else { 
      synchronized (tieLock) { 
       synchronized (fromAcct) { 
        synchronized (toAcct) { 
         new Helper().transfer(); 
        } 
       } 
      } 
     } 
    } 

    interface DollarAmount extends Comparable<DollarAmount> { 
    } 

    interface Account { 
     void debit(DollarAmount d); 

     void credit(DollarAmount d); 

     DollarAmount getBalance(); 

     int getAcctNo(); 
    } 

    class InsufficientFundsException extends Exception { 
    } 
} 
+0

你对此有特别的问题吗?从目前发布的内容不清楚。 – eldarerathis 2011-04-06 18:27:47

+0

这是教科书示例如何创建死锁。以相同的顺序获取锁。 – 2011-04-06 18:30:35

+0

这是正确的,这是避免死锁的解决方案,但它不能解决问题。 – user695398 2011-04-06 18:33:59

回答

0

您的示例说明它实际上是正确的。

情况1:Thread1.transfer(Obj1, Obj2)

在这种情况下,fromHash < toHash所以第一锁是在fromAcct PARAM或Obj1,第二个是在toAcct PARAM或Obj2

情况2:Thread1.transfer(Obj2, Obj1)

在这种情况下,fromHash > toHash所以第一个锁在toAcct param或Obj1,第二个在fromAcct param或Obj2

锁定顺序相同,所以不会发生死锁。

+0

美丽,谢谢你的帮助。 – user695398 2011-04-06 18:52:55