锁(objlocker)是否使该对象在应用程序范围内线程安全?和是自动线程安全的静态成员
本文关键字:线程 安全 静态成员 范围内 应用程序 objlocker 是否 对象 | 更新日期: 2023-09-27 17:48:50
锁定对象时,该对象是否在整个应用程序中被锁定?
例如,在Nutshell第19.6.1节"线程安全和.NET框架类型"中的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会自动使静态方法线程安全吗?还是由开发人员决定?
谢谢,John
还有一点需要注意,静态构造函数是由运行时以线程安全的方式执行的。如果您正在创建一个singleton并将其声明为:
public class Foo
{
private static Foo instance = new Foo();
public static Foo Instance
{
get { return instance; }
}
}
然后它就可以穿线了。但是,如果您在Instancegetter中实例化了一个新的Foo,那么您将需要编写自己的线程安全性(即锁定对象)
class UsefulStuff {
object _TheLock = new object { };
public void UsefulThingNumberOne() {
lock(_TheLock) {
//CodeBlockA
}
}
public void UsefulThingNumberTwo() {
lock(_TheLock) {
//CodeBlockB
}
}
}
CodeBlockA
和CodeBlockB
被阻止在不同的线程中同时执行,因为它们都被锁定在同一对象实例_TheLock
上。
_TheLock
上的方法本身完全不受影响。
CLR不会自动使静态方法成为线程安全的;你必须自己做。
lock(list)将该对象用作锁,因此,如果另一个线程使用lock(列表)(使用相同的"list"对象)到达另一个点,则另一个螺纹将阻塞,直到第一个线程释放锁为止。
需要明确的是,lock(foo)并不是"锁定foo对象",而是获取与foo对象关联的锁,这样关键部分(构造"lock(o)stmt"中的语句)只有在当前线程获取锁时才运行。