从this thread跳下,我正在尝试使用 ConcurrentDictionary 复制以下内容:
public static class Tracker
{
private static Dictionary<string, int> foo = new Dictionary<string, int>();
private static object myLock = new object();
public static void Add(string bar)
{
lock(myLock)
{
if (!foo.ContainsKey(bar))
foo.Add(bar, 0);
foo[bar] = foo[bar] + 1;
}
}
public static void Remove(string bar)
{
lock(myLock)
{
if (foo.ContainsKey(bar))
{
if (foo[bar] > 0)
foo[bar] = foo[bar] - 1;
}
}
}
}
我最初的尝试是:
public static class Tracker2
{
private static ConcurrentDictionary<string, int> foo =
new ConcurrentDictionary<string, int>();
public static void Add(string bar)
{
foo.AddOrUpdate(bar, 1, (key, n) => n + 1);
}
public static void Remove(string bar)
{
// Adding a 0'd item may be ok if it wasn't there for some reason,
// but it's not identical to the above Remove() implementation.
foo.AddOrUpdate(bar, 0, (key, n) => (n > 0) ? n - 1 : 0);
}
}
这是正确的用法吗?我会避免以下情况吗:
- 线程 1:调用 Add("a"),foo["a"] 现在是 1。
- 线程 1 换出线程 2。
- 线程 2:调用 Remove("a"),foo["a"] 现在为 0。
- 线程 2 换出线程 1。
- 线程 1:请求 foo["a"] 并假定值为 1 但实际上为 0。
最佳答案
您无法仅通过使用 ConcurrentDictionary
来避免您担心的不一致。您需要更强大、更强大的东西来保证这一点。在着手解决问题之前问问自己是否真的需要那种程度的一致性。龙在那里。
换句话说,ConcurrentDictionary
只确保多个线程访问字典不会搞砸。当多个线程连续拉取时,它不保证值的一致性。它不能阻止你搬起石头砸自己的脚。
关于c# - .NET4.0 : Thread-Safe Updating of ConcurrentDictionary<TKey, T值>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4234525/