C# .net中的线程安全队列(列表)

C# .net中的线程安全队列(列表),c#,multithreading,thread-safety,lucene.net,C#,Multithreading,Thread Safety,Lucene.net,我需要创建一个线程安全的项目列表,添加到lucene索引中 以下线程是否安全 public sealed class IndexQueue { static readonly IndexQueue instance = new IndexQueue(); private List<string> items = new List<string>(); private IndexQueue() { } public static Inde

我需要创建一个线程安全的项目列表,添加到lucene索引中

以下线程是否安全

public sealed class IndexQueue
{
    static readonly IndexQueue instance = new IndexQueue();
    private List<string> items = new List<string>();

    private IndexQueue() { }

    public static IndexQueue Instance {
        get { return instance; }
    }

    private object padlock = new object();

    public void AddItem(string item) {
        lock (padlock) {
            items.Add(item);
        }
    }
}
公共密封类索引队列
{
静态只读IndexQueue实例=新建IndexQueue();
私有列表项=新列表();
私有索引队列(){}
公共静态IndexQueue实例{
获取{return instance;}
}
私有对象挂锁=新对象();
公共无效附加项(字符串项){
锁(挂锁){
项目。添加(项目);
}
}
}
即使从内部列表中获取项目,也需要锁定吗

我们的想法是,我们将运行一个单独的任务,从indexqueue中获取项目,并将它们添加到lucene索引中

谢谢 本

即使从内部列表中获取项目,也需要锁定吗

进行修改时,List类不是线程安全的。如果出现以下情况,则有必要锁定:

  • 您使用来自多个线程的类的单个实例
  • 在修改或读取列表时,列表的内容可能会更改
假设第一个是真的,否则你就不会问这个问题了。第二种方法显然是正确的,因为
Add
方法修改列表。所以,是的,你需要它


当您向类中添加允许您读回项的方法时,还需要锁定,重要的是,您必须使用与在
AddItem
中相同的锁定对象

您的实现似乎是线程安全的,尽管在读取
项时也需要锁定
——如果存在并发的
添加操作,则无法安全地读取。如果您曾经枚举过,那么您也需要锁定它,并且需要与枚举器一样长的寿命


如果您可以使用.NET4,我强烈建议您查看名称空间。它有一些经过良好测试且性能相当好的集合,这些集合是线程安全的,并且实际上围绕多线程访问进行了优化;虽然检索不是本质上不安全的操作,但是如果您还写入列表,则在写中间运行检索的风险。


如果这将像传统队列一样运行,则尤其如此,在传统队列中,检索实际上会从列表中删除检索到的值。

在.NET 4中有线程安全实现(如果您甚至可以使用4),不确定您是否知道,因为我看到您正在运行自己的…谢谢大家。我想,
System.Collections.Concurrent对你没有多大用处。没有与之等价的
列表
,即使有,您也可能需要应用自己的锁定,以使项的枚举成为原子的。这实际上取决于您希望多个线程如何感知枚举。这是先进先出的行为对我们有用。然而,正如您正确地说的,我们确实需要在对Contains的调用周围引入一个锁,以防止重复的项被添加到队列中——只是为了防止出现争用情况。