2010-05-18 35 views
3

以下代码摘自MS用于创建新安全令牌服务网站的(Windows Identity Foundation SDK)模板。锁定(syncRoot)如何在静态方法上有意义?

public static CustomSecurityTokenServiceConfiguration Current 
{ 
    get 
    { 
     var key = CustomSecurityTokenServiceConfigurationKey; 

     var httpAppState = HttpContext.Current.Application; 

     var customConfiguration = httpAppState.Get(key) 
      as CustomSecurityTokenServiceConfiguration; 

     if (customConfiguration == null) 
     { 
      lock (syncRoot) 
      { 
       customConfiguration = httpAppState.Get(key) 
        as CustomSecurityTokenServiceConfiguration; 

       if (customConfiguration == null) 
       { 
        customConfiguration = 
         new CustomSecurityTokenServiceConfiguration(); 
        httpAppState.Add(key, customConfiguration); 
       } 
      } 
     }  
     return customConfiguration; 
    } 
} 

我对多线程编程比较陌生。我假设lock声明的原因是在两个Web请求同时到达Web站点的情况下使此代码线程安全。

但是,我会认为使用lock (syncRoot)没有意义,因为syncRoot引用了当前实例,该方法正在运行......但这是一种静态方法!

这有什么意义?

+2

'syncRoot'定义在哪里? – Paolo 2010-05-18 15:22:58

+0

@Paolo:这是一个很好的问题。话虽如此,我假定它是一个'static'变量或由一个Singleton返回的名称。 – Powerlord 2010-05-18 15:42:00

+0

@Bemrose:我所做的假设是'syncRoot'是一个静态类字段,它始终保存相同的实例:'private readonly object syncRoot = new object();'。当然'syncRoot'可以定义如下:'private object syncRoot {get {return new object(); }}。在这种情况下,我们会遇到麻烦:-) – Steven 2010-05-18 15:46:45

回答

6

C#lock语句不锁定方法,而是锁定在提供给它的对象上。在你的情况syncRoot。因为此syncRoot对象只有一个实例,所以这可确保CustomSecurityTokenServiceConfiguration类仅为该应用程序域创建一次。所以该属性可以被调用并且并行执行。但是,lock { ... }内的块永远不会并行调用。但是,它可以被多次调用,这就是额外的if (customConfiguration == null)语句在lock块中正在执行的操作。这种机制被称为双重检查锁。

+0

好的。仔细查看这段代码后,我发现'syncRoot'被声明为一个静态对象。我只是有点困惑,因为我习惯了'syncRoot'作为.net枚举类的成员出现。 它看起来像这块代码是'syncRoot'被使用的唯一地方,所以它必须被声明为锁定代码块的明确目的。 – 2010-05-18 16:29:21

+0

这是在.NET中使用'lock'关键字进行锁定的常用方法:创建一个专用只读对象并将其用作锁定对象。 – Steven 2010-05-18 19:25:43