7

ICollection の syncroot のポイントを理解しようとしています。コレクションをロックしないのはなぜですか?

lock(myCollection)
{
    //do stuff to myCollection
}

lock(myCollection.SyncRoot)
{
    //do stuff to myCollection
}
4

2 に答える 2

8

通常、スレッドの安全性が深刻な懸念事項である場合、これらのオプションはどちらも避けます。

通常、はるかに優れたオプションは、独自のプライベート変数を維持し、それが必要なすべてのメソッド (コレクションにアクセスするパブリック API 全体を含む) でロックすることです。

本当の危険は、外部の世界に公開されている、または公開される可能性のある型をロックすることで、「外部の世界」が同期を台無しにする可能性を開くことです。複数のロックが使用されている場合、デッドロックが発生する可能性があります (予期しないものに対して外部がロックしている場合)。

プライベート変数を作成し、それを排他的にロックすることで、状況を「制御」しています。これにより、何が起こっているのかがより明確になります。さらに、ロックが非常に明確であるため、特に後でコードを保守するときに、複数のオブジェクト間の同期が容易になります。

于 2011-06-29T18:05:47.410 に答える
1

コレクション全体をロックしているロック(this)を行うと信じているため、SyncRootをロックしないでください。 ロックする場合は、オブジェクトを作成してロックする必要があります。例えば

public class MyClass
{
   get {return lock(_lockObject) _myCollection ; }
   set {lock(_lockObject) _myCollection.Add(value); }


   private List<string> _myCollection = new List<string>();
   private object _lockObject = new object();
}

より明確にするために、lock(myCollection.SyncRoot) と lock(myCollection) は同じことを行います。
プロパティ SyncRoot は次のように見えるため

get {これを返します。}

于 2011-06-29T18:04:17.190 に答える