2011-01-31 40 views
2

我有一个控制器类,看起来像这样的实例属性一些代码:volatile关键字,并锁定了实例属性

public class Controller 
{ 
    private static volatile Controller _instance; 
    private static object syncRoot = new Object(); 

    private Controller() { } 

    public static Controller Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       lock (syncRoot) 
       { 
        if (_instance == null) 
         _instance = new Controller(); 
       } 
      } 

      return _instance; 
     } 
    } 

    public void Start() 
    { 

    } 
} 

通过msdn docs on the volatile keyword看完后,我不知道,如果第二个空检查是多余的,也不论是否更好的方式来写,吸气将是这样的:

get 
{    
    lock (syncRoot) 
    { 
     if (_instance == null) 
      _instance = new Controller(); 
    }    

    return _instance; 
} 

这两种实现的是多线程性能和DRY'ness(去除冗余)好?

+0

这不是,你想在锁定 – 2011-01-31 19:40:44

回答

13

这被称为“双重检查锁定”模式。这是一个低锁优化的尝试,因此非常危险。

该模式不能保证在CLR v1.0上正常工作。在后续版本中是否有这样的保证是一个有争议的问题;一些文章说是,有些人说不。这很混乱。

我会完全避免它,除非你有一个非常好的理由,假设锁定解决方案不足以满足您的需求。我会使用更高级别的基元,例如Lazy<T>,由Joe Duffy等专家编写。他们更可能是正确的。

这个问题的

The need for volatile modifier in double checked locking in .NET

重复查看详细解答那里获取更多信息。特别是,如果你曾经打算写任何低锁码你绝对要阅读万斯的文章:

http://msdn.microsoft.com/en-us/magazine/cc163715.aspx

和乔的文章:

http://www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx

注意,万斯的文章使声称双重检查锁定保证在CLR v2中可用。我不清楚在文章中讨论的保证实际上是在CLR v2中实现的;我从来没有从任何人那里得到过直接的答复,并且听说他们都没有按照规定实施。再一次,当你自己做低锁定的东西时,你就没有网络的空中飞人;如果可能的话可以避开它。

+0

之前检查一下,这是很好的东西要知道,谢谢Eric! – BrokenGlass 2011-01-31 19:55:21

0

执行此操作的经典方法是double-checked locking:在获取锁定以减少开销(获取锁定相对昂贵)之前检查一次 - 然后在锁定确认尚未设置之后再次检查。

编辑:正如指出Lazy<T>是一个更好的选择在这里,我在这里离开这个答案完整性。

if (_instance == null) 
{ 
    lock (syncRoot) 
    { 
     if (_instance == null) 
      _instance = new Controller(); 
    }    
} 

return _instance; 
7

一个更好的选择是使用Lazy<T>

private static readonly Lazy<Controller> _instance = new Lazy<Controller> 
               (() => new Controller()); 
private Controller() { } 

public static Controller Instance 
{ 
    get 
    { 
     return _instance.Value; 
    } 
} 

但是,如果你在.NET 4之前套牢的版本,我建议你阅读Jon Skeet's article on Singletons in C#。它讨论了上述技术的优缺点,并为.NET 3.5及更早版本提供了一个更好的实例化单例。

0

你想锁定的对象前检查,以便不发生不必要的锁定 你也想锁定,以避免对象

第一没有必要的,但强烈建议对性能的缘故

的多个实例后检查