多个文本表明,当在.NET中实现双重检查锁定时,您锁定的字段应该应用volatile修饰符。但是为什么呢?考虑以下示例:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
为什么“锁(syncRoot)”不能实现必要的内存一致性?在"lock“语句之后,读和写都是易失性的,因此实现了必要的一致性,这是真的吗?
发布于 2009-12-28 06:56:13
我想我已经找到我要找的东西了。详细信息请参阅本文- http://msdn.microsoft.com/en-us/magazine/cc163715.aspx#S10。
综上所述,在这种情况下,确实不需要.NET挥发性修饰符。然而,在较弱的内存模型中,在延迟启动的对象的构造函数中进行的写入可能会在写入字段后延迟,因此其他线程可能会在第一个if语句中读取损坏的非空实例。
发布于 2009-12-27 08:19:22
这是一个关于使用带有双重检查锁定的易失性的很好的帖子:
http://tech.puredanger.com/2007/06/15/double-checked-locking/
在Java中,如果目标是保护变量,那么如果变量被标记为易失性,就不需要加锁
https://stackoverflow.com/questions/1964731
复制相似问题