2

この質問は何度も聞かれたと思いますが、この概念を明確にしたいと思います。

最近、2 つのスレッドが 2 つの異なる関数で同じリストにアクセスしているときに、バグに遭遇しました。適切なロックがないと、どのようなシナリオで問題が発生する可能性がありますか? 2 番目の関数にロックがあり、2 つのスレッドは関連していませんが、同じリストを操作しています。1 つは追加、もう 1 つは空のリストとの交換です。どのような状況で例外をキャッチしますか? 助けてください。

擬似コード:

List<SomeClass> list=new List<SomeClass>();

  object mutex=new object();

スレッド 1 はこの関数にアクセスし、リストを変更します。

public void Manipulate()
{

  //some operation
  list.add(new SomeClass());

}

スレッド 2 はこの関数にアクセスし、リストをクリアします。

public void SwapList()
{
   List<SomeClass> cls=new List<SomeClass>();
   try
   {
     while(Thread2.isAlive)
     {
       //some operation
       if(list.Count()>0)
       {
         lock(mutex)
         {
           swap(ref list,ref cls)
         }
       }
     }
  }
  catch(exception ex)
  {
  }
}
public void swap(List<SomeClass> a, List<SomeClass> b)
{
  List<SomeClass> temp=a;
  a=b;
  b=temp;
}
4

2 に答える 2

2

を使用するとすぐにロックが開始されますlist

lock(mutex)
{
  if(list.Count()>0)    
  {
     swap(ref list,ref cls)
   }
}

そして、それを使用したいすべての人がそれをロックする場合にのみ役立ちます(スレッド 1 のロックはどこにありますか?)

編集:

スレッド 1 でのロックは、競合を回避するために行う必要があります。

public void Manipulate()
{
  lock(mutex)
  {
    //some operation
    list.add(new SomeClass());
  }
}

Thread-Safe Collectionsについて読むと役立つと思います-そのような場合、ほとんどの場合、ハンドルのロックを回避できます。

例外のキャッチについて - この特定のケースでは、同時実行のケースからスローされた例外は見られません。remove メソッドがあり、リスト内の特定のアイテムを交換しようとすると、それが発生した可能性があります。

しかし、他にもいくつかの例外が発生する可能性があるため、例外をキャッチするブロックは配置せず、処理できる例外のみを配置します(例外を飲み込むのは悪い習慣です)。

于 2013-10-18T23:43:51.570 に答える