并发字典锁定
Concurent dictionary locking
我目前正在阅读我们外部人员交付的代码,但我不理解这部分代码:
private ConcurrentDictionary<Int64, Person> users = new ConcurrentDictionary<Int64, Person>();
private Dictionary<String, Int64> connectionIndex = new Dictionary<String, Int64>();
public Boolean AddNewUser(Int64 userId, Person user) {
Boolean added = false;
lock (users) {
if (users.Select(X=>X.Key==userId).Count()>0)
{
Person usrtmp = new Person();
users.TryRemove(userId,out usrtmp)
}
added = users.TryAdd(userId, user);
if (added)
{
connectionIndex.Add(user.ConnectionId, userId);
}
}
return added;
}
为什么 "users concurrent dictionary" 在对该字典的任何操作完成之前被锁定?有必要吗?从我的角度来看,不需要 lock 语句,因为 ConcurrentDictionary 包含线程安全操作。我对吗?
此外,当您在 ConcurrentDictionary 上使用 .Count() 或 Key、Value 操作时,我知道 "performance issue" 。从这个角度来看,LINQ 语句可以吗?
感谢您的回答。
Why "users concurrent dictionary" is locked before any operation on that dictionary is done? Is it necessary?
考虑到他们的使用方式,这把锁当然是必要的。他们在多个不同的字典上执行多个操作,重要的是在发生这种情况时,没有其他线程以任何方式与任何一个字典交互。这样做需要 lock
。
您可以解除锁定的唯一方法是,如果您到达共享数据结构的唯一用途是对单个并发字典的一个单一 方法调用的地步。在不知道确切要求的情况下,我们无法知道这是否可能,但如果需要两个词典,那肯定不是。
现在,鉴于您已将自己置于始终需要锁定对并发字典的所有访问的位置,因此没有理由使用并发字典而不是常规字典;您已经决定使用自己的同步。
From my point of view is lock statement unnecessary because ConcurrentDictionary contains thread-safe operations. Am I right?
没有。对于新手来说,非并发字典不加锁是无法访问的
Also, I know about "performance issue" when you use .Count() or Key, Value operations on ConcurrentDictionary. Is it LINQ statement OK in this point of view?
出于很多原因,这是一个可怕的想法。它试图通过字典进行线性搜索以查看键是否存在。你不应该永远那样做。您应该使用 ContainsKey
。此外,如果在尝试删除密钥之前检查密钥是否存在是没有意义的,您可以尝试将其删除并查看会发生什么。如果您还没有锁定它也是完全不安全的,因为其他人可能会在您迭代字典时更改它,并且它可能会在您搜索后更改,从而在做任何事情之前进行检查毫无意义,因为您不能假设您刚刚检查的内容是真实的。
我目前正在阅读我们外部人员交付的代码,但我不理解这部分代码:
private ConcurrentDictionary<Int64, Person> users = new ConcurrentDictionary<Int64, Person>();
private Dictionary<String, Int64> connectionIndex = new Dictionary<String, Int64>();
public Boolean AddNewUser(Int64 userId, Person user) {
Boolean added = false;
lock (users) {
if (users.Select(X=>X.Key==userId).Count()>0)
{
Person usrtmp = new Person();
users.TryRemove(userId,out usrtmp)
}
added = users.TryAdd(userId, user);
if (added)
{
connectionIndex.Add(user.ConnectionId, userId);
}
}
return added;
}
为什么 "users concurrent dictionary" 在对该字典的任何操作完成之前被锁定?有必要吗?从我的角度来看,不需要 lock 语句,因为 ConcurrentDictionary 包含线程安全操作。我对吗? 此外,当您在 ConcurrentDictionary 上使用 .Count() 或 Key、Value 操作时,我知道 "performance issue" 。从这个角度来看,LINQ 语句可以吗?
感谢您的回答。
Why "users concurrent dictionary" is locked before any operation on that dictionary is done? Is it necessary?
考虑到他们的使用方式,这把锁当然是必要的。他们在多个不同的字典上执行多个操作,重要的是在发生这种情况时,没有其他线程以任何方式与任何一个字典交互。这样做需要 lock
。
您可以解除锁定的唯一方法是,如果您到达共享数据结构的唯一用途是对单个并发字典的一个单一 方法调用的地步。在不知道确切要求的情况下,我们无法知道这是否可能,但如果需要两个词典,那肯定不是。
现在,鉴于您已将自己置于始终需要锁定对并发字典的所有访问的位置,因此没有理由使用并发字典而不是常规字典;您已经决定使用自己的同步。
From my point of view is lock statement unnecessary because ConcurrentDictionary contains thread-safe operations. Am I right?
没有。对于新手来说,非并发字典不加锁是无法访问的
Also, I know about "performance issue" when you use .Count() or Key, Value operations on ConcurrentDictionary. Is it LINQ statement OK in this point of view?
出于很多原因,这是一个可怕的想法。它试图通过字典进行线性搜索以查看键是否存在。你不应该永远那样做。您应该使用 ContainsKey
。此外,如果在尝试删除密钥之前检查密钥是否存在是没有意义的,您可以尝试将其删除并查看会发生什么。如果您还没有锁定它也是完全不安全的,因为其他人可能会在您迭代字典时更改它,并且它可能会在您搜索后更改,从而在做任何事情之前进行检查毫无意义,因为您不能假设您刚刚检查的内容是真实的。