我想知道这段代码是否是线程安全的,以及为什么不是这种情况。
static IMyInterface _myinterface;
public static IMyInterface someStuff
{
get
{
if (_myinterface== null)
{
_myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
}
return _myinterface;
}
}
谢谢!
答案 0 :(得分:4)
正如其他人所说,事实并非如此。但是,有一些选项可以使它从普通锁定或双重检查模式进行线程安全appart - 这不能保证在CLR的所有(可能的)实现上都有效。
另请注意,除非您期望高争用,否则实际上不需要双重检查锁定,并且几乎没有什么区别。错误相对容易(参见其中一个答案中的其他(最初)错误的实现作为一个很好的例子)。
有关详情,请参阅主题Jon Skeet's article。
答案 1 :(得分:1)
对我而言,事实并非如此。 因为在唯一的方法之间确定是在它上面加一个锁。它可能有两个线程进入if语句!
http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=vs.80%29.aspx
答案 2 :(得分:1)
没有。你需要使用锁。
private static readonly object m_lock = new object();
private static IMyInterface _myinterface;
public static IMyInterface someStuff
{
get
{
lock(m_lock)
{
if (_myinterface == null)
{
//create instance
}
return _myinterface;
}
}
}
答案 3 :(得分:1)
不,不,你想做更像这样的事情。请注意_myinterface==null
上的双重检查。这是因为在您第一次检查后,另一个线程可能已经在锁中创建它。因此,一旦锁定,您需要仔细检查。
static IMyInterface _myinterface;
private static object lockObj = new object();
public static IMyInterface someStuff
{
get
{
if (_myinterface== null)
{
lock(lockObj)
{
if (_myinterface== null)
{
_myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
}
}
}
return _myinterface;
}
答案 4 :(得分:1)
这不是因为可能有多个初始化线程会同时尝试访问单例。
这可行:
static object _lock=new object();
static IMyInterface _myinterface;
public static IMyInterface someStuff
{
get
{
lock (_lock) {
if (_myinterface== null)
{
_myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
}
}
return _myinterface;
}
}
答案 5 :(得分:0)
不,不是。
为什么?
两个来自someStuff
的来电已经超过if(_myInterface null)
,但被中断_myInterface = MYServiceLoc...
。第二个线程完全进入并在进入睡眠状态之前完成。第二个醒来,分配到_myInterface。
两者最终调用MyServiceLocator ... GetInstance(),都分配给_myInterface,两者都可以为_myInterface返回不同的值。
答案 6 :(得分:0)
不,可能会发生两个不同的线程实例化不同的实例,并且会删除之前保存的_ myInterface
的值。
想象一下,线程#1进入了if
块
if (_myinterface== null)
{
// ... here
和线程#2也读取_ myinterface
并进入此块,此时Thread#1实例化了对象并更新了_myinterface
的引用。
但同时Thread#2已缓存_myinterface
的值(它为NULL)并创建一个由Thread#1存储的新对象和ower写值。
通过lock()包装getter,这样只有一个线程可以输入(参见关于双重锁定的其他答案)