为什么在从字典中读取时会锁定

eas*_*der 9 c# multithreading caching dictionary locking

我对正在阅读的书中的代码列表,Nutshell中的C#3以及线程感到困惑.在关于应用程序服务器中的线程安全的主题中,下面的代码是作为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

作者解释了为什么RetrieveUser方法没有锁定,这是为了避免长时间锁定缓存.
我很困惑为什么要锁定TryGetValue和字典的更新,因为即使上面的字典正在被更新两次,如果2个线程同时使用相同的未检索的id调用.

通过锁定字典读取实现了什么?
非常感谢您提出的所有意见和见解.

SLa*_*aks 16

这个Dictionary<TKey, TValue>不是线程安全的.

如果一个线程将一个键写入字典而另一个线程读取字典,则可能会搞乱.(例如,如果写操作触发数组调整大小,或者两个键是哈希冲突)

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

  • 当 Dictionary 由单线程设置一次并且之后仅由多个线程读取时,我还需要锁定它吗?可能不是,但另一种意见会很有用 (2认同)