【发布时间】:2016-05-05 22:26:22
【问题描述】:
我可能在某处遗漏了一些非常明显的文档,但静态只读成员变量是否可以保证正确初始化以用作锁定对象?
简而言之,我有一个对外部资源执行操作的库类,该外部资源在任何时候都应该只有一个实例接触它(不必担心另一个进程,它只在一个进程上)。库类本身可以在多个线程中有多个实例,因此为了确保一次只有一个实例访问所述资源,我需要使用锁。
我见过很多这样的锁对象声明。
private static readonly object _lockObj = new object();
这能否保证多个线程不会因为时机不当而同时初始化两个对象并锁定两个对象?或者我应该像这样创建锁定对象。
private static readonly Lazy<object> _lockObj = new Lazy<object>(() => new object());
附:我指的是 C# 的 lock(_lockObj){...} 关键字用于锁定。
【问题讨论】:
-
可以对任何对象进行锁定。如果你说的是真的,
static readonly字段可能有多个值,这不是预期的。只要他们访问的是同一个类,你就可以开始了。小心泛型类 ;) -
CLR 保证每个 appdomain 都会初始化一次类型。静态字段初始值设定项在类型的静态构造函数主体之前的类型初始值设定项内运行(如果有的话)。因此,假设两个线程在同一个 appdomain 中激活一个方法,那么就不可能出现它们获得不同锁对象的竞争。
-
如果它不能像这样工作,那么我看不出你的解决方案会有什么帮助。您只需将问题转移到您有两个
Lazy实例然后初始化两个不同对象的风险。
标签: c# multithreading lazy-initialization