1

マルチスレッドのシナリオで使用されるクラスにリストがあるとしましょう。

public class MyClass
{
     List<MyItem> _list= new List<MyItem>();
     protected object SyncRoot { 
      get {
         return ((IList)_list).SyncRoot;
        }
     }

     public void Execute1()
     {
        lock(SyncRoot)
        {
             foreach(var item in _list) DoSomething(item);
        }
     }

     public void Execute2()
     {
         Item[] list;
         lock(SyncRoot)
         {
            list=_list.ToArray();
         }
           for(var i=0;i<list.Length;i++) DoSomething(list[i]);
      }
}

メソッドExecute1は、スレッドセーフな方法でリストを列挙する「通常の」方法です。しかし、Execute2はどうですか? このアプローチはまだスレッドセーフですか?

4

2 に答える 2

2

リスト (のコピー) へのアクセスは、どちらのシナリオでもスレッドセーフです。もちろん、MyItem 要素は同期されません。

2 番目の形式は少し高価に見えますが、DoSomething()s の実行中に元の形式で追加/削除できます。アレイは一種のスナップショットのように機能します。それが要件に一致する場合、役立つ可能性があります。も使用できることに注意してくださいToList()

于 2012-04-10T07:27:54.493 に答える
1

の他のすべての使用も同じステートメント_listで保護されている限り、安全です。lockリストへの排他的アクセス権を取得し、その内容をコピーしてから、そのコピーで作業しています (スコープ設定により、排他的アクセス権も持っています)。一見すると少し無駄ですが、特定の状況下では正当なアプローチです。

于 2012-04-10T07:16:23.017 に答える