2009-07-18 7 views
1

xmlサイトマップファイル用に私自身のプロバイダを実装しようとしています。これで私は反射鏡を経由して、デフォルトのMicrosoft XmlSiteMapProviderを調査し始めていると私は私を混乱さスニペットを発見したので、ここではそれが行く:私が理解できないコードを切り捨てた質問

SiteMapNode node = this._siteMapNode; 
if (node != null) 
{ 
    return node; 
} 
XmlDocument configDocument = this.GetConfigDocument(); 
lock (base._lock) 
{ 
    **if (this._siteMapNode == null)** 
    {...// more code 

さて、まず私たちは、ときにノードがnullでないかどうかをチェックし、小切手は私たちがもう一度それを見て通過しました。このIf文は冗長ではありませんか?それともロックと関係がありますか?

答えて

1

複数のスレッドがほぼ同時にこのコードを実行していた場合の状況を想像してみてください。

両方のスレッドが最初のヌルチェックに達し、新しいノードを作成することになります。ロックは、1つのスレッドだけが2番目のヌルブロックに入り、新しいノードを作成できるようにすることです。

質問するかもしれません:なぜ最初のヌルチェックの前にロックしないのですか?その理由は、nodeではなくである場合、特に複数のスレッドが実行されている場合にコードを可能な限り高速にしたいので、オブジェクトがまだヌルであることが予想される場合にのみロックし、ロック。

3

はい、ロックに関連しています。最初のヌルチェックとロックの間に、同じコードを実行してノードを作成した別のスレッドがあるため、最初のスレッドがロックを取得したときに、それはより遅くないことがあります。これは、あなたが遅延ロード静的リソースを持っていたときに心に留めておくことが重要です。

private static List<string> _someStringList; 
private static object _lock = new object(); 
public static List<string> SomeStringList 
{ 
    get 
    { 
     if (_someStringList == null) 
     { 
      // if more than one thread try to do this at the same time 
      // it may be that the other thread has already gotten the lock 
      // and is creating the object at this point 
      lock (_lock) 
      { 
       // now we have the lock, so we check again to make 
       // sure that another thread did not get here first 
       if (_someStringList == null) 
       {     
        // now we know for sure that the object is not yet created, and 
        // also cannot have been created since we have the lock 
        _someStringList = new List<string>(); 
       } 
      } 
     } 
     return _someStringList; 
    } 
} 

これをやって、あなたがロックに使用するオブジェクトが何かのために使用されていないことをお勧めしますが、それが作成されていることこの単一の目的のために。

2

はい、nullを2回確認することはDouble-Checked Lockingと呼ばれます。 nullをチェックしてロックを取得し、再びnullをチェックします。最初のヌルチェックが成功すると、オブジェクトはすでに初期化されているため、ロック/初期化のステップを再度実行する必要はないため、ロックオーバーヘッドを減らすことです。最初のヌルチェックとロックの取得の間に別のスレッドによってオブジェクトが初期化されている可能性があるため、2回目のヌルチェックが必要です。

関連する問題