1

オブジェクトをロックすると、そのオブジェクトはアプリケーション全体でロックされますか?

たとえば、C# 3.0 の要約セクション 19.6.1「スレッド セーフティと .NET Framework 型」のこのスニペットは次のとおりです。

static void AddItems(  )
  {
    for (int i = 0; i < 100; i++)
      lock (list)
        list.Add ("Item " + list.Count);

    string[] items;
    lock (list) items = list.ToArray(  );
    foreach (string s in items) Console.WriteLine (s);
  }

最初のロック:

lock (list)
        list.Add ("Item " + list.Count);

別のスレッドがアクセスできないようにします:

lock (list) items = list.ToArray(  );

または両方を同時に実行できますか?

また、CLR は自動的に静的メソッドをスレッド セーフにしますか? それとも開発者次第?

ありがとう、ジョン

4

3 に答える 3

5

注意すべきもう 1 つの点は、静的コンストラクターがランタイムによってスレッドセーフな方法で実行されることです。シングルトンを作成し、次のように宣言する場合:

public class Foo
{
    private static Foo instance = new Foo();

    public static Foo Instance
    {
        get { return instance; }
    }
}

その後、スレッドセーフになります。ただし、Instance getter内で新しい Foo をインスタンス化する場合は、独自のスレッド セーフを記述する必要があります (つまり、オブジェクトをロックします)。

于 2008-11-08T09:42:25.070 に答える
3

CLR は、静的メソッドを自動的にスレッド セーフにするわけではありません。あなたは自分でそれをしなければなりません。

lock(list) はそのオブジェクトをロックとして使用するため、別のスレッドが lock(list) (同じ 'list' オブジェクトを使用) で別のポイントに到達すると、最初のスレッドがロックを解放するまで他のスレッドがブロックされます。

明確にするために、lock(foo) は「foo オブジェクトをロックする」のではなく、foo オブジェクトに関連付けられたロックを取得するため、クリティカル セクション (構成要素「lock(o) stmt」内のステートメント) は次の場合にのみ実行されます。現在のスレッドがロックを取得しました。

于 2008-11-08T04:13:55.547 に答える
3
class UsefulStuff {
    object _TheLock = new object { };
    public void UsefulThingNumberOne() {
        lock(_TheLock) {
            //CodeBlockA
        }
    }
    public void UsefulThingNumberTwo() {
        lock(_TheLock) {
            //CodeBlockB
        }
    }
}

CodeBlockACodeBlockBは、両方とも同じオブジェクト インスタンスでロックされているため、異なるスレッドで同時に実行することはできません_TheLock

メソッド_TheLock自体はまったく影響を受けません。

于 2008-11-08T04:19:20.807 に答える