2016-11-29 68 views
1

我有一些代碼可以訪問我想定期刷新內容的字典。包含的對象在多個線程之間共享。使用鎖來實時更新字段

我不太瞭解鎖,但在我的腦海中,我想象兩個線程擊中它,第一個運行在下一個之前完成。這看起來像是一個相當不好的事情發生,如果鎖的主體更新共享值作爲第一個線程更新它,然後所有掛起的線程然後會做同樣的。這是我對它的工作原理的理解。

所以它有點情景依賴,但在我的情況下,我來到了這個

if (DateTimeOffset.Now.Subtract(_lastResolve) > TimeSpan.FromMinutes(2)) 
      { 
       var copy = _configCache; 
       lock (_lock) 
       { 
        if (copy == _configCache) 
        { 
         var t = ResolveSettings(); 
         t.Wait(); 
         _configCache = t.Result; 
        } 
       } 
      } 

return _configCache; 

因此鎖定之前,它創造我們要更新字典的參考副本,並在進入鎖體確認copy ref仍然是針對相同的字典。

所以我的問題是兩重摺疊,是我對鎖定行爲的理解是正確的,其次是我的方法來處理這個特定問題的聲音?

謝謝

回答

2

這被稱爲雙重檢查鎖定,這是解釋e。 G。在MSDNSO與單身模式。

爲了使引用的代碼更加兼容,您可能再次在鎖體中檢查了_lastResolve。但是,由於日期時間操作的成本很高,指針的分配和檢查可能是實現所需要的更輕量級的方法。

您應該考慮將_configCache聲明爲volatile,以防止編譯器進行不必要的優化。

希望這會有所幫助。

+0

謝謝尤爾根。我會閱讀易變的。 – Sam

相關問題