2009-06-18 9 views
2

である場合にのみ、いくつかの方法でロック[削除]をクリックしますが、[取得]に入力できます。最初は私が考える:スレッドは次のように私はクラス(単純化の例を)持っている特定の方法

public void Add(Item item) { lock(addLock) { /* ... */ } } 
    public void Remove(Item item) { lock(removeLock) { /* ... */ } } 

    public object Clone(Item item) 
    { 
     lock(addLock) 
     { 
      lock(removeLock) 
      { 
       /* ... */ 
      } 
     } 
    } 

これは動作します(と思う)が、特定の欠点があります。 私は2つのスレッドが互いをブロックするために追加入力する必要はありません* - *私はコード のそれより深く取り扱っております

:私はその後、私はこの

private volatile bool cloning = false; // notice the volatile keyword 

    public void Add(Item item) 
    { 
     int i = 0; 
     while(cloning) 
     { 
      if (i++ > 20) 
       throw new TimeoutException(); 
      Thread.Sleep(50); // waits 50 milliseconds 
     } 
     /* ... */ 
    } // and the same for Remove 

    public object Clone() 
    { 
     cloning = true; 
     try 
     { 
      /* do the cloning */ 
     } finally { cloning = false; } 
    } 

のしかし、このアプローチを考え

を追加または削除するために、各コールのロック・オーバーヘッドを耐えなければならないでしょう

  • スレッドが
  • の追加と削除]を実行し終えていない一方で、より複雑な
  • クローンを入力することができますです不自然

は私がReadWriterLockSlimに短い一見を与えているが、中に収まるようには思えないようです私のシナリオ。

Cloneメソッドが時間がかかる(1秒以上かかる場合があります。コレクションは大量です)、今回の変更は列挙子(foreachループで使用される)を吹き飛ばします。はい、基本的なキーコレクションはIEnumerable以外のものを公開していないので、foreachを使用する必要があります。

何がよろしいですかをお勧めしますか?

答えて

1

ReaderWriterLockSlimがあなたのシナリオに合わない理由をもっと説明できますか?

確かに、古典的な使い方では使用しませんが、あなたの作家としてのCloneメソッドと、読者の追加/削除メソッドを考慮してください。

[編集]もう1つのこと:このルートに進む場合は、ReaderWriterLockSlimを「逆方向」に使用している理由を文書化して、次のコードを読む人(または6ヶ月)が何が起こっているのかを理解してください。

+0

はい、私は同じことを考えました:クローン - 作家、読者としての追加と削除。 1つは、操作名が反転していることを意味します。つまり、AddとRemoveは実際に書き込みを行い、Cloneは読み取りを行います。しかし、これは非問題のようなものです。 2番目は、書き込み中に読み出し操作をブロックし、読み出し中に書き込み操作をブロックするかどうかを実際には分かりません。しかし、再び、私はドキュメンテーションを再度読むべきです。私はあなたがそれについて正しいと確信しています。それは私の質問に完全に答えるだろう。 :D TX! –

+0

私はドキュメントを読んでおり、スレッドとロックの間の可能な相互作用を明確に説明した素敵なテーブルがあります。ありがとうございました。これは私の答えと思われる。 –

+0

@ Jared - 通常の使用法でOPが説明した方法ではなく、確実に複数の追加/削除を同時に行い、クローンのみが読み取り/書き込みをブロックすることを望みます。 –

関連する問題