C# .net中的线程安全队列(列表)
我需要创建一个线程安全的项目列表,添加到lucene索引中 以下线程是否安全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
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的调用周围引入一个锁,以防止重复的项被添加到队列中——只是为了防止出现争用情况。