【问题标题】:Intelocked.Exchange instead of ReaderWriterLockSlimIntelocked.Exchange 而不是 ReaderWriterLockSlim
【发布时间】:2021-03-23 17:48:42
【问题描述】:

在多线程应用程序中,我有一个可供多个线程访问的字典,用于获取特定键的值。还有一种使用 Quartz.Net 的机制来更新这个字典。 我正在尝试找到使更新后的字典可用于以线程安全方式阅读的最佳方法。 最初,我将 ReadWriterLockSlim 视为一种解决方案,但当我搜索可能的性能损失时,我可能遇到了 Interlocked.Exchange 和可用于对象的重载。所以我的问题是,它可以在这种情况下使用吗?我提供了它的用法的代码示例。

非常感谢

public class SingletonDictionaryHolder
{
    private Dictionary<string, Person> MyDictionary;

    public Person GetPerson(string key)
    {
        return MyDictionary[key];
    }

    public void UpdateDictionary(Dictionary<string, Person> updated)
    {
        Interlocked.Exchange(ref MyDictionary, updated);
    }
}  

 

编辑:

由于有人反对,我添加了更多信息:

此处介绍另一个相关问题:https://softwareengineering.stackexchange.com/questions/294514/does-readerwriterlockslim-provide-thread-safety-and-speed-efficiency-compared-t

请注意以下段落:“如果写入很少,您可以通过将集合视为不可变的并在它更改时生成一个全新的列表来获得更好的性能。然后您可以使用 Interlocked.CompareExchange 更新对列表的引用以线程安全的方式。这应该可以防止读者需要制作防御性副本(如果阅读比写作更普遍,这应该是一个巨大的胜利)并消除对锁定的需要。”

关于 Intelocked.CompareExchange 方法,这里提供了一个见解:Using Interlocked.CompareExchange with a class

请注意,正确的架构设计是使用默认线程安全的 MemoryCache 和 pub/sub 机制来反映缓存项的更改 - 但是它不是由我设计的,我怀疑是否有希望近期的变化。

【问题讨论】:

  • 请不要尝试编写自己的同步方案,很可能会自取其辱。
  • 我永远不会尝试,我正在寻找最佳选择。 Interlocked.CompareExchange VS ReaderWriterLockSlim。
  • 字典创建后是不可变的吗?
  • @TheodorZoulias 是的,字典不会改变
  • 不,我不认为抄袭 Eric Lippert 会成为我的一个好答案。我建议您自己answer your question,因为您对自己正在尝试做的事情有更好的了解,并且可以为未来的读者提供更有用的答案。

标签: c# multithreading interlocked readerwriterlockslim


【解决方案1】:

在真正有用的 cmets 的指导下回答我自己的问题。 线程安全不需要 Interlock.Exchange,因为引用分配在所有 .Net 平台中都是线程安全的。

所以更新后的对象可以安全地分配给原始对象。更新后将访问相关对象的线程将获得新的对象,这对我的场景来说完全没问题。

对于遇到此问题的未来读者,请查看:reference assignment is atomic so why is Interlocked.Exchange(ref Object, Object) needed?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多