2010-05-26 89 views
3

這個簡單的緩存類是否需要線程同步...如果我刪除了鎖_syncLock語句會遇到任何問題嗎?我想我可以刪除鎖作爲參考應正確更新對嗎? ...我認爲如果客戶端代碼遍歷GetMyDataStructure方法並且被替換,會發生whar嗎?這個簡單的緩存類是否需要線程同步?

編輯:我已經用TryGetValue樣式方法替換了GetMyDataStructure並刪除了所有的鎖定....這應該沒問題吧?

public bool TryGetValue(int id, out MyDataStructure myDataStructure) 
    { 
     return _cache.TryGetValue(id, out myDataStructure); 
    } 

謝謝!

public sealed class Cache 
{ 
    private readonly object _syncLock = new object(); 
    private IDictionary<int, MyDataStructure> _cache; 

    public Cache() 
    { 
     Refresh(); 
    } 

    public void Refresh() 
    { 
     lock (_syncLock) 
     { 
      _cache = DAL.GetMyDataStructure(); 
     } 
    } 

    public IDictionary<int, MyDataStructure> **GetMyDataStructure**() 
    { 
     lock (_syncLock) 
     { 
      return _cache; 
     } 
    } 
} 
+1

您需要回顧一下您提出的問題並選擇一個有助於您的答案,它鼓勵人們幫助您,因爲我們獲得了提供最佳答案的聲望點。它看起來像一個下方的勾選框,您可以在上面或下面投票。 – 2010-05-26 10:28:56

回答

1

Cache類真的只告訴我們一個單一的參考。那不是本身需要同步,因爲它是原子的。然而!這真的取決於打電話給與字典。如果他們只讀,那麼它會工作 - 但如果他們中的任何人將要添加/刪除/交換值,那麼它將分崩離析。

我會試圖公開(而不是字典)一個類似索引器的不可變類型 - 所以沒有調用者可以通過改變某些東西來破壞聚會。


編輯後;只有TryGetValue版本不再使呼叫者可以打破它,所以應該沒問題。

0

我認爲這將是安全的,因爲引用賦值是原子的(除非存在隱式轉換)。

1

由於對引用類型的賦值是原子的(請參閱C#標準的5.5節),因此您不需要在Refresh中的lock

至於鎖定在GetMyDataStructure,你可能實際上需要 - 原因涵蓋here。雖然我不是特別確定。

+0

我已經用TryGetValue樣式方法替換了GetMyDataStructure並刪除了所有的鎖定....這應該沒問題吧? ... 以上。謝謝 – DayOne 2010-05-26 10:50:55

0

在GetMyDataStructure鎖幾乎沒做什麼...

你最好想想你將可以在你的代碼被asiigned靜態或其他長期生活的對象_cache的舊實例做什麼。這將是地獄,真的。不要使用這種方法。