锁定对象时,该对象是否在整个应用程序中被锁定?

例如,在Nutshell Section 19.6.1“Thread Safety and .NET Framework Types”中来自C#3.0的这个片段:

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会自动使您的静态方法线程安全吗?或者这取决于开发人员?

谢谢, 约翰

有帮助吗?

解决方案

class UsefulStuff {
    object _TheLock = new object { };
    public void UsefulThingNumberOne() {
        lock(_TheLock) {
            //CodeBlockA
        }
    }
    public void UsefulThingNumberTwo() {
        lock(_TheLock) {
            //CodeBlockB
        }
    }
}
阻止

CodeBlockA CodeBlockB 在不同的线程中同时执行,因为它们都被锁定在同一个对象实例上 _TheLock

_TheLock 本身的方法完全不受影响。

其他提示

另外需要注意的是静态构造函数是由运行时以线程安全的方式执行的。如果要创建单例并将其声明为:

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

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

然后它将是线程安全的。但是,如果你在Instance getter中实例化一个新的Foo ,那么你需要编写自己的线程安全(即锁定一个对象)

CLR不会自动使静态方法成为线程安全的;你必须自己做。

lock(list)使用该对象作为锁,因此如果另一个线程到达另一个带有lock(list)的点(具有相同的'list'对象),则另一个线程将阻塞,直到第一个线程释放锁。

要清楚,lock(foo)不会“锁定foo对象”,而是获取与foo对象关联的锁,以便关键部分(构造中的语句“lock(o)stmt” ;)仅在当前线程获得锁定时运行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top