2016-12-11 3 views
1

LinkedListのNodeクラス内で初期化されたReentrantLockを使用してJavaでハンドオーバーハンドリングを実装しようとしていますが、私はそれを修正する方法がわかりません。どんな助けもありがとう。デッドロックを手渡しで解決するJavaでリンクされたリストをロックする

// Insert value for key. 
public boolean add(K key, V value) { 
    // Require key != null and value != null 
    // Get hash code 
    int hash = key.hashCode(); 
    Node pred = null, curr = null; 

    try { 
     pred = head; 
     pred.lock.lock(); 
     curr = pred.next; 
     curr.lock.lock(); 

     while(curr.hash <= hash) { 
      if(key.equals(curr.key)) { // key present, update value 
       curr.value = value; 
       return false; 
      } 
      pred = curr; 
      pred.lock.lock(); 
      curr = curr.next; 
      curr.lock.lock(); 
     } 

     // key not present 
     Node node = new Node(hash, key, value); 
     node.next = pred.next; 
     pred.next = node; 

     return true; 
    } finally { 
     curr.lock.unlock(); 
     pred.lock.unlock(); 
    } 
} 
// Remove key/value pair 
public boolean remove(K key) { 
    // Require key != null 
    // Get hash code 
    int hash = key.hashCode(); 
    Node pred = null, curr = null; 

    try { 
     // Predecessor node 
     pred = this.head; 
     pred.lock.lock(); 
     //Current node 
     curr = pred.next; 
     curr.lock.lock(); 

     // traversing list 
     while(curr.hash <= hash) { 
      if(key.equals(curr.key)) { // key present, update value 
       pred.next = curr.next; 
       return true; 
      } 
      pred.lock.unlock(); 
      pred = curr; 
      curr = curr.next; 
      curr.lock.lock(); 
     } 

     // key not found 
     return false; 
    }finally { 
     curr.lock.unlock(); 
     pred.lock.unlock(); 
    } 
} 
+1

whileループでノードをロックしていて、後でaddメソッドで解放しないようです。 – hal

+0

http://cs.oswego.edu/pipermail/concurrency-interest/2007-April/004076.html –

答えて

2

whileループのadd()では、実際にはいくつかの問題があります。

  1. predノードはロック解除されません。
  2. currノードを2回ロックします。

predノードはどのようにロック解除されませんか。だからここ

pred = curr; 
pred.lock.lock(); 

、あなたの地元のpredノードの参照、そして今predcurrは、同じノードに両方のポイントを上書きします。したがって、pred参照を上書きする前に、そのノードをロック解除したままにしておく必要があります。

currノードはどのように2回ロックされますか?

pred = curr; 
pred.lock.lock(); 

再び、上記と同じ理由。 predはここではcurrと同じノードで、方法の冒頭で既にcurrをロックしています。

したがって、pred.lock.lock()を呼び出すとデッドロックが発生します。

読み込みする必要があります。

pred.lock.unlock(); 
pred = curr; 
curr = curr.next; 
curr.lock.lock(); 
0

あなたのwhileループ持つ2つのロック文を、それがロック解除(PREDの)と(更新された現在の)ロックをする必要がありながら。

電子メールで講師にご連絡ください。

関連する問題