我想知道锁定一个集合是否有任何缺点,比如List<T>
、HashSet<T>
或Dictionary<TKey, TValue>
而不是简单的object
。
注意:在下面的例子中,这是唯一发生锁的地方,它不是从多个地方被锁的,但是静态方法可以从多个线程调用。此外,_dict
永远不会在GetSomething
方法之外访问。
我当前的代码如下:
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
public static string GetSomething(string key)
{
string result;
if (!_dict.TryGetValue(key, out result))
{
lock (_dict)
{
if (!_dict.TryGetValue(key, out result))
{
_dict[key] = result = CalculateSomethingExpensive(key);
}
}
}
return result;
}
另一个开发人员告诉我,锁定集合会导致问题,但我对此表示怀疑。如果我这样做,我的代码会更有效吗?
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
private static readonly object _syncRoot = new object();
public static string GetSomething(string key)
{
string result;
if (!_dict.TryGetValue(key, out result))
{
lock (_syncRoot)
{
if (!_dict.TryGetValue(key, out result))
{
_dict[key] = result = CalculateSomethingExpensive(key);
}
}
}
return result;
}
最佳答案
如果你把你的收藏对外公开,那么,是的,这可能是个问题。通常的建议是锁定那些您独占的、永远不会被您影响之外的代码意外锁定的内容。这就是为什么通常情况下,最好锁定一些您从未考虑公开的对象(即为此目的创建的特定锁对象)。这样,当你的记忆力衰退时,你可能永远不会得到意想不到的结果。
要更直接地回答您的问题:在混合中添加另一个对象永远不会更有效,但是将通常被视为良好的编码实践放在一些可感知的、但无法测量的效率之前可能是过早发生的一种操作。我赞成最佳实践,直到它明显造成了瓶颈。