我想知道是否有任何缺點來鎖定集合,如List<T>
,HashSet<T>
或Dictionary<TKey, TValue>
而不是簡單的object
。鎖定集合與syncRoot的任何缺點?
注:在下面的例子,那就是鎖發生的唯一的地方,它沒有被從多個地方鎖定,但靜態方法可以從多個線程調用。此外,_dict
永遠不會在GetSomething
方法之外訪問。
我當前的代碼如下所示:
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
public static string GetSomething(string key)
{
string result;
if (!_dict.TryGetValue(key, out result))
{
lock (_dict)
{
if (!_dict.TryGetValue(key, out result))
{
_dict[key] = result = CalculateSomethingExpensive(key);
}
}
}
return result;
}
另一名開發者告訴我,鎖定在一個集合會導致一些問題,但我懷疑。如果我這樣做,我的代碼會更高效嗎?
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
private static readonly object _syncRoot = new object();
public static string GetSomething(string key)
{
string result;
if (!_dict.TryGetValue(key, out result))
{
lock (_syncRoot)
{
if (!_dict.TryGetValue(key, out result))
{
_dict[key] = result = CalculateSomethingExpensive(key);
}
}
}
return result;
}
您是否考慮將_dict和GetSomething()移入單獨的類中?它顯然做了一些不同於班裏其他人的事情。 (它看起來像一個Memoization模式) – Sjoerd 2010-10-11 23:52:16
你必須聲明_dict是不穩定的,纔有機會做到正確。另請參閱有關Double-Checked Locking及其缺陷的此答案:http://stackoverflow.com/questions/394898/double-checked-locking-in-net/394932#394932 – Sjoerd 2010-10-11 23:55:40
@Sjoerd volatile不需要用C#double - 在許多情況下檢查。然而,這裏的雙重檢查不會有效,因爲它不是雙重檢查的字段讀取,而是雙重檢查的方法調用,只有當調用的方法是原子的時候才起作用,這不是,所以經過了雙重檢查在這裏顯然是錯誤的。 – 2010-10-12 01:50:53