2008-11-08 52 views
1

当你锁定一个对象时,该对象锁定在整个应用程序中?锁(objlocker)是否使该对象线程安全的应用程序广泛?并且静态成员是否自动线程安全?

例如,该段从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自动使您的静态方法线程安全吗?或者是由开发人员决定?

感谢, 约翰

回答

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

CodeBlockACodeBlockB从在不同的线程的同时执行阻止,因为它们都被锁定在同一个对象实例_TheLock

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

+0

感谢您为我清理它。 – John 2008-11-08 04:33:53

3

的CLR不会自动使静态方法是线程安全的;你必须自己做。 (列表)使用该对象作为锁,因此如果另一个线程到达具有锁(列表)的另一个点(具有相同的'列表'对象),另一个线程将阻塞,直到第一个线程释放该锁。 (foo)不会“锁定foo对象”,而是它获取与foo对象关联的锁,以便关键部分(构造中的语句“lock(o)stmt” )只在当前线程获得锁定时运行。

+0

感谢您的快速响应! – John 2008-11-08 04:18:09

5

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

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

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

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

相关问题