c# - .NET4.0 : Thread-Safe Updating of ConcurrentDictionary<TKey, T值>

标签 c# multithreading .net-4.0

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. 线程 1:调用 Add("a"),foo["a"] 现在是 1。
  2. 线程 1 换出线程 2。
  3. 线程 2:调用 Remove("a"),foo["a"] 现在为 0。
  4. 线程 2 换出线程 1。
  5. 线程 1:请求 foo["a"] 并假定值为 1 但实际上为 0。

最佳答案

您无法仅通过使用 ConcurrentDictionary 来避免您担心的不一致。您需要更强大、更强大的东西来保证这一点。在着手解决问题之前问问自己是否真的需要那种程度的一致性。龙在那里。

换句话说,ConcurrentDictionary 只确保多个线程访问字典不会搞砸。当多个线程连续拉取时,它不保证值的一致性。它不能阻止你搬起石头砸自己的脚。

关于c# - .NET4.0 : Thread-Safe Updating of ConcurrentDictionary<TKey, T值>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4234525/

相关文章:

c# - 如何在 WPF 中从 UTF-8 字符串编码为\解码?

linux - 一个进程占用多少核?

c# - 查询任务的 Result 属性导致线程池创建一个新线程

java - 获取所有以指定Runnable运行的线程

c# - 为什么 RowVersion 属性在发生两个并发更改时不引发乐观并发异常?

c# - 如何绕过 "Internal .NET Framework Data Provider error 1025."?

c# - 如何解码可移植类库 (PCL) 中的 URL?

.net - 实体以不正确的顺序保存而没有暴露外键

c# - 在C#中处理大文本文件

c# - 从 Access 数据库获取数据的正确方法