【问题标题】:Do i need a lock on a list? C#我需要锁定列表吗? C#
【发布时间】:2009-04-25 10:41:20
【问题描述】:

我用默认值填充了几个列表,将它们粘贴到一个结构中,然后将结构传递给几个线程。每个线程都有不同的范围,因此线程 1 将访问列表 [0 到 199] 线程 2 将访问 [200 - 400] 等。我需要锁吗?我什么时候需要它?我可以使用我的多个线程访问列表,而无需使用锁。但是,如果我的主线程想要读取列表中的数据(从不写),我需要一个锁吗?我确定我不知道,但我想在实施之前问一下。

-编辑-

谢谢大家,你回答了我的问题。 (只要有人不反驳当前的答案,我稍后会接受)

【问题讨论】:

    标签: c# multithreading locking


    【解决方案1】:

    如果您不修改集合,则根本不需要锁定。

    如果您想使用其中一个线程修改集合,您可能需要查看ReaderWriterLock

    彼得的评论值得注意。正如上面的 MSDN 链接所指出的,如果您使用的是 .NET 3.5,则应该考虑使用 ReaderWriterLockSlim 类。然而,这个想法是一样的。

    【讨论】:

    • 或新改进的 ReaderWriterLockSlim msdn.microsoft.com/en-us/library/…
    • 确保你运行测试——如果你没有持有足够长的锁来引起很多争用,一个标准的锁可能最终会更快。如果您几乎没有争用,SpinLock(PFX/.NET 4.0 中的新功能)可能是未来更好的选择。
    • @Jonathan,绝对是。在大规模并行平台上,自旋锁几乎总是表现得更好
    【解决方案2】:

    如果您绝对确定您没有修改实际列表(添加项目、删除项目等),则不需要锁定。

    【讨论】:

      【解决方案3】:

      如果你不写,你就不需要锁。但是,如果您在其他线程中写入,那么您应该有一个锁。即使这些线程仅访问特定范围,如果您将节点添加到可能导致问题的列表中。如果您不更改列表结构而仅更改节点中的任何内容,那么我认为没有问题。

      【讨论】:

      • 这不是真的。另一个线程可能会在您阅读时删除或修改您的收藏
      • 我认为 Megacan 的意思是,如果线程只在列表中设置值,如 list[i] = value,并且对于不同的线程总是不同的索引并且没有其他变化,它应该在没有锁的情况下是线程安全的。应该并不意味着它实际上是 - 我不知道 List 的内部结构足以说它是线程安全的。不过,我认为在这种情况下,应该使用数组 - 在这种情况下,数组是线程安全的。
      • 大小不变的 List 在当前实现下是线程安全的(它在内部是一个数组)。如果要更改大小,则它不是线程安全的(因为可能必须为任何添加重新分配该数组)。
      • 我应该指出——是的,在这种情况下,数组会更好。这样你就不会依赖 List 的实现在内部使用数组。
      • 他在帖子中说,线程将访问列表的不同部分。我的回答考虑到了这一点
      【解决方案4】:

      在您的 struct 对象中,我至少会将变量标记为 ReadOnly 并且可能是新的 ReadOnlyCollection

      public struct MyStruct
      {
          private readonly ReadOnlyCollection<int> _myInts;
      
          public MyStruct(ReadOnlyCollection<int> ints)
          {
              _myInts = ints;
          }
      }
      

      【讨论】:

        【解决方案5】:

        您是否考虑过使用数组?只要您不在两个线程中访问相同的索引,数组就是线程安全的。另外,不改变大小会更快。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-21
          相关资源
          最近更新 更多