2017-12-06 10 views
0

私は、デッドロックの例を探していると、このコードに出くわした:それはデッドロックが発生しないように複数のオブジェクトトランザクションのデッドロックを回避する最も良い方法は?

package com.example.thread.deadlock._synchronized; 

public class BankAccount { 
    double balance; 
    int id; 

    BankAccount(int id, double balance) { 
     this.id = id; 
     this.balance = balance; 
    } 

    void withdraw(double amount) { 
     // Wait to simulate io like database access ... 
     try {Thread.sleep(10l);} catch (InterruptedException e) {} 
     balance -= amount; 
    } 

    void deposit(double amount) { 
     // Wait to simulate io like database access ... 
     try {Thread.sleep(10l);} catch (InterruptedException e) {} 
     balance += amount; 
    } 

    static void transfer(BankAccount from, BankAccount to, double amount) { 
     synchronized(from) { 
      from.withdraw(amount); 
      synchronized(to) { 
       to.deposit(amount); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     final BankAccount fooAccount = new BankAccount(1, 100d); 
     final BankAccount barAccount = new BankAccount(2, 100d); 

     new Thread() { 
      public void run() { 
       BankAccount.transfer(fooAccount, barAccount, 10d); 
      } 
     }.start(); 

     new Thread() { 
      public void run() { 
       BankAccount.transfer(barAccount, fooAccount, 10d); 
      } 
     }.start(); 

    } 
} 

どのようにtransfer方法を変更するのでしょうか?最初の考えはすべてのアカウントの共有ロックを作成することですが、もちろんすべての同時実行性を殺すだけです。だから、トランザクションに関与する2つのアカウントだけをロックし、他のアカウントに影響を与えないようにするには良い方法がありますか?

答えて

4

一つの方法でロックしようとする前に

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

のでfrom.withdraw(amount)が呼び出された後、fromのロックが解除されます。

この場合、すべてのBankAccountオブジェクトに対して合計発注を作成することになります。幸運にも私たちは使用できるIDを持っているので、まず低いIDをロックしてから、もう一方のIDをロックすることができます。

これは、同じIDを持つBankAccountオブジェクトがないことを前提としていますが、これは合理的な仮定のようです。

-2

入れ子の代わりに2つの同期ブロックを別々に使用します。それは常に同じ順序でオブジェクトをロックしているマルチロック状況でデッドロックを回避するためにto

+0

別のトランザクションのためにトランザクション中に1人のメンバーがお金を持っていない場合、2つの同期ブロックを使用すると問題が発生する – Ferrybig

+0

トランザクションではないことが分かりますか? –

関連する問題