问题描述
在我正在阅读的一本书C#3中,我感到困惑的是一个代码清单,一个Nutshell的线程。在应用程序服务器中的线程安全性主题中,以下代码作为UserCache的示例给出:
static UserCache类
{
静态字典<整型,使用者名称> _users = new Dictionary< int,User>();
内部静态用户GetUser(int id)
{
用户u = null;
lock(_users)//为什么要锁定这个???
if(_users.TryGetValue(id,out u))
return u;
u = RetrieveUser(id); //从数据库中获取的方法
lock(_users)_users [id] = u; //为什么要锁定???
return u;
}
}
作者解释为什么RetrieveUser方法不在锁定,这是为了避免锁定缓存更长的时间。
我很困惑为什么锁定TryGetValue和字典的更新,因为即使上述字典正在更新两次,如果2个线程同时呼叫同一个未解决的身份。
通过锁定字典阅读实现了什么?
非常感谢您的所有评论和见解。
Dictionary< TKey,TValue>
class 。
如果一个线程写入一个字典的关键字,而不同的线程读取字典,它可能会搞砸了。 (例如,如果写入操作触发数组调整大小,或者两个键是散列冲突)
因此,代码使用锁来防止并发写入。
I am confused by a code listing in a book i am reading, C# 3 in a Nutshell, on threading.In the topic on Thread Safety in Application Servers, below code is given as an example of a 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;
}
}
The authors explain why the RetrieveUser method is not in a lock, this is to avoid locking the cache for a longer period.
I am confused as to why lock the TryGetValue and the update of the dictionary since even with the above the dictionary is being updated twice if 2 threads call simultaneously with the same unretrieved id.
What is being achieved by locking the dictionary read?
Many thanks in advance for all your comments and insights.
The Dictionary<TKey, TValue>
class is not threadsafe.
If one thread writes one key to the dictionary while a different thread reads the dictionary, it may get messed up. (For example, if the write operation triggers an array resize, or if the two keys are a hash collision)
Therefore, the code uses a lock to prevent concurrent writes.
这篇关于为什么在从字典阅读时锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!