为什么 ConcurrentDictionary 有 AddOrUpdate 和 GetOrAdd,而 Dictionary 没有?
Why ConcurrentDictionary has AddOrUpdate and GetOrAdd, but Dictionary has not?
在.NET Framework 中,有Dictionary
和ConcurrentDictionary
。
这些提供方法,如 Add
、Remove
等...
我知道在设计多线程程序的时候,为了线程安全,我们用ConcurrentDictionary
代替Dictionary
我想知道为什么ConcurrentDictionary
有AddOrUpdate
、GetOrAdd
和类似的方法,而Dictionary
没有。
我们总是喜欢下面的代码从 Dictionary
:
中获取对象
var dict = new Dictionary<string, object>();
object tmp;
if (dict.ContainsKey("key"))
{
tmp = dict["key"];
}
else
{
dict["key"] = new object();
tmp = new object();
}
但是使用ConcurrentDictionary
时,类似的代码只有一行。
var conDict = new ConcurrentDictionary<string, object>();
var tmp = conDict.GetOrAdd("key", new object());
我希望 .NET 有这些方法,但为什么没有?
因为这样的方法是:
在并发上下文中工作的最低限度。您不能在不锁定的情况下将 Get
和 Add
分成两个单独的步骤,并且仍然会产生正确的结果。
当为 Dictionary<TKey, TValue>
实现时,它隐含地表示某种级别的线程安全,就好像 Dictionary<TKey, TValue>
可以正确处理这个问题一样。它不能,所以它只是没有实现。这不会阻止您制作扩展方法来做类似的事情。
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<TKey, TValue> valueGenerator)
{
//
// WARNING: this method is not thread-safe and not intended as such.
//
if (!dict.TryGetValue(key, out TValue value))
{
value = valueGenerator(key);
dict.Add(key, value);
}
return value;
}
在.NET Framework 中,有Dictionary
和ConcurrentDictionary
。
这些提供方法,如 Add
、Remove
等...
我知道在设计多线程程序的时候,为了线程安全,我们用ConcurrentDictionary
代替Dictionary
我想知道为什么ConcurrentDictionary
有AddOrUpdate
、GetOrAdd
和类似的方法,而Dictionary
没有。
我们总是喜欢下面的代码从 Dictionary
:
var dict = new Dictionary<string, object>();
object tmp;
if (dict.ContainsKey("key"))
{
tmp = dict["key"];
}
else
{
dict["key"] = new object();
tmp = new object();
}
但是使用ConcurrentDictionary
时,类似的代码只有一行。
var conDict = new ConcurrentDictionary<string, object>();
var tmp = conDict.GetOrAdd("key", new object());
我希望 .NET 有这些方法,但为什么没有?
因为这样的方法是:
在并发上下文中工作的最低限度。您不能在不锁定的情况下将
Get
和Add
分成两个单独的步骤,并且仍然会产生正确的结果。当为
Dictionary<TKey, TValue>
实现时,它隐含地表示某种级别的线程安全,就好像Dictionary<TKey, TValue>
可以正确处理这个问题一样。它不能,所以它只是没有实现。这不会阻止您制作扩展方法来做类似的事情。public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<TKey, TValue> valueGenerator) { // // WARNING: this method is not thread-safe and not intended as such. // if (!dict.TryGetValue(key, out TValue value)) { value = valueGenerator(key); dict.Add(key, value); } return value; }