c# - 为什么在从字典中读取时锁定

标签 c# multithreading caching dictionary locking

我对正在阅读的一本书中的代码列表感到困惑,C# 3 in a Nutshell,关于线程。 在应用服务器中的线程安全主题中,给出了以下代码作为 UserCache 的示例:

static class UserCache
{
    static Dictionary< int,User> _users = new Dictionary< int, User>();

    internal static User GetUser(int id)
    {
        User u = null;

        lock (_users) // Why lock this???
            if (_users.TryGetValue(id, out u))
                return u;

        u = RetrieveUser(id); //Method to retrieve from databse

        lock (_users) _users[id] = u; //Why lock this???
            return u;
    }
}

作者解释了为什么RetrieveUser方法不在锁中,这是为了避免长时间锁定缓存。
我对为什么锁定 TryGetValue 和字典更新感到困惑,因为如果 2 个线程同时使用相同的未检索 ID 调用,即使使用上述字典也会更新两次。

锁定已读字典的作用是什么?
非常感谢您的所有评论和见解。

最佳答案

Dictionary<TKey, TValue>is not threadsafe .

如果一个线程将一个键写入字典,而另一个线程读取字典,它可能会搞砸。 (比如写操作触发数组resize,或者两个key是hash冲突)

因此,代码使用锁来防止并发写入。

关于c# - 为什么在从字典中读取时锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3439690/

相关文章:

c# - 字符串的索引可以有多长?

java - java中Long,long,Double,double等变量自动装箱或拆箱时,读写操作是原子的吗?

c++ - 如果 pthread_cond_signal 是线程中的最后一次调用,是否存在数据竞争?

php - 如何在 IE (PHP) 中下载服务器文件的更新版本?

caching - 在ASP.Net Core上具有自动重新生成的内存中缓存

c# - Microsoft OData 无法仅在 $filter (v7) 中使用日期

c# - 使用 Entity Framework 从 Web 服务访问数据?

c# - 在不知道类型的情况下实例化子类

c++ - 协程 TS 2017 的实现示例

http - 如何清除winsock缓存的http重定向(301永久移动)