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

前端之家收集整理的这篇文章主要介绍了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摘要.在你深入研究多线程代码之前,你应该理解这一点.选择正确的锁定机制可以产生巨大的性能差异.

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

猜你在找的C#相关文章