c# – 仅在修改vs整个方法时锁定

什么时候应该使用锁?仅在修改数据或访问数据时?
public class Test {
    static Dictionary<string,object> someList = new Dictionary<string,object>();

    static object syncLock = new object();

    public static object GetValue(string name) {
        if (someList.ContainsKey(name)) {
            return someList[name];
        } else {
            lock(syncLock) {
                object someValue = GetValueFromSomeWhere(name);
                someList.Add(name,someValue);
            }
        }
    }
}

是否应该锁定整个块或者是否可以将其添加到实际修改中?我的理解是,仍然可能存在一些竞争条件,其中一个呼叫可能没有找到并开始添加它,而另一个呼叫可能也会遇到相同的情况 – 但我不确定.锁定仍然令人困惑.我没有遇到上述类似代码的任何问题,但到目前为止我可能很幸运.上面的任何帮助都会被评估,以及关于如何/何时锁定对象的任何好资源.

解决方法

您也必须在读取时锁定,或者您可以获得不可靠的数据,或者甚至是并发修改在物理上更改目标数据结构时的异常.

在上面的例子中,您需要确保多个线程不会同时尝试添加值,因此在检查它是否已存在时至少需要一个读锁定.否则多个线程可能决定添加,找不到该值(因为此检查未锁定),然后所有尝试依次添加(获取锁定后)

如果您有多次读取且只有少量写入,则可以使用ReaderWriterLockSlim.在上面的代码中,一旦您决定需要添加它,您将获得读锁以进行检查并升级到写锁.在大多数情况下,只需要一个读锁(允许您的读取器线程仍然并行运行).

一个可用的.Net 4锁定原语here摘要.在你深入研究多线程代码之前,你应该理解这一点.选择正确的锁定机制可以产生巨大的性能差异.

到目前为止,你是幸运的,这是正确的 – 这是并发错误的常见特征.如果没有针对性的负载测试,它们通常难以重现,这意味着正确的设计(当然,详尽的测试)对于避免令人尴尬和混乱的生产错误至关重要.

相关文章

原文地址:http://msdn.microsoft.com/en-us/magazine/cc163...
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采...
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下...
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Mic...
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么