锁定对象时,该对象是否在整个应用程序中被锁定?
例如,Cuts 3.0中的这个片段在Nutshell Section 19.6.1“Thread Safety and .NET Framework Types”中:
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会自动使您的静态方法线程安全吗?或者这取决于开发人员?
谢谢, 约翰
答案 0 :(得分:5)
另外需要注意的是静态构造函数是由运行时以线程安全的方式执行的。如果要创建单例并将其声明为:
public class Foo
{
private static Foo instance = new Foo();
public static Foo Instance
{
get { return instance; }
}
}
然后它将是线程安全的。但是,如果你在Instance getter中实例化一个新的Foo ,那么你需要编写自己的线程安全(即锁定一个对象)
答案 1 :(得分:3)
CLR不会自动使静态方法成为线程安全的;你必须自己做。
lock(list)使用该对象作为锁,因此如果另一个线程到达另一个带有lock(list)的点(具有相同的'list'对象),则另一个线程将阻塞,直到第一个线程释放锁。
要清楚,lock(foo)不会“锁定foo对象”,而是获取与foo对象关联的锁,以便关键部分(构造中的语句“lock(o)stmt”)仅在当前线程获得锁定时运行。
答案 2 :(得分:3)
class UsefulStuff {
object _TheLock = new object { };
public void UsefulThingNumberOne() {
lock(_TheLock) {
//CodeBlockA
}
}
public void UsefulThingNumberTwo() {
lock(_TheLock) {
//CodeBlockB
}
}
}
阻止 CodeBlockA
和CodeBlockB
在不同的线程中同时执行,因为它们都被锁定在同一个对象实例_TheLock
上。
_TheLock
本身的方法完全不受影响。