rya*_*ner 7 c# concurrency singleton locking thread-safety
我已经阅读了很多关于双重检查锁定的危险,我会努力远离它,但据说说我认为它们是一个非常有趣的阅读.
我正在阅读Joe Duffy关于使用双重检查锁定实现单例的这篇文章:http: //www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx
而他似乎提出的(变体)解决方案是这样的:
class Singleton {
private static object slock = new object();
private static Singleton instance;
private static int initialized;
private Singleton() {}
public Instance {
get {
if (Thread.VolatileRead(ref initialized) == 0) {
lock (slock) {
if (initialized == 0) {
instance = new Singleton();
initialized = 1;
}
}
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
}
我的问题是,是否仍然存在写入重新排序的危险?具体来说这两行:
instance = new Singleton();
initialized = 1;
Run Code Online (Sandbox Code Playgroud)
如果这些写入被反转,那么其他一些线程仍然可以读取null.
我认为关键在于链接文章(http://msdn.microsoft.com/en-us/magazine/cc163715.aspx#S5).具体来说,MS实现的.NET 2.0内存模型具有以下属性:
写入不能移动到同一线程的其他写入.
Duffy提到在IA-64上做了很多工作来支持这个:
我们通过st.rel指令确保写入在IA-64上具有"释放"语义来实现这一点.单个st.rel x保证,至少在x的新值对另一个逻辑处理器可见时,每个逻辑处理器似乎必须出现导致其执行的任何其他加载和存储(在物理指令流中).可以为LOAD赋予'acquire'语义(通过ld.acq指令),这意味着在ld.acq x之后出现的任何其他加载和存储似乎都不会在加载之前发生.
请注意,Duffy还提到这是MS特定的保证 - 它不是ECMA规范的一部分(至少在2006年的文章撰写时).所以,Mono可能不那么好.
归档时间: |
|
查看次数: |
814 次 |
最近记录: |