我有一个管理大量数据队列的代码,它是锁定的女巫锁语句,以确保一次只有一个线程在处理它。
队列中数据的顺序非常重要,每个线程及其参数都可以添加或从中获取。
如何确保线程像我的队列一样按 FIFO 的顺序排队启动?锁定语句是否保证这一点?
var t = new Thread(() => parse(params)); //This is how I start my threads.
t.Start();
不,lock
语句不保证 FIFO 排序。每阿尔巴哈里:
如果多个线程争用锁,它们将在"就绪队列"上排队,并以先到先得的方式授予锁(需要注意的是,Windows 和 CLR 行为的细微差别意味着有时会违反队列的公平性)。
如果要确保按 FIFO 顺序检索项目,则应改用ConcurrentQueue<T>
集合。
编辑:如果面向 .NET 2.0,则可以对并发线程安全队列使用自定义实现。这是一个微不足道的:
public class ThreadSafeQueue<T>
{
private readonly object syncLock = new object();
private readonly Queue<T> innerQueue = new Queue<T>();
public void Enqueue(T item)
{
lock (syncLock)
innerQueue.Enqueue(item);
}
public bool TryDequeue(out T item)
{
lock (syncLock)
{
if (innerQueue.Count == 0)
{
item = default(T);
return false;
}
item = innerQueue.Dequeue();
return true;
}
}
}
Lock 不保证先进先出访问。另一种方法是,如果受 .NET 2.0 的限制,则队列。请记住,Queue
不是线程安全的,因此您应该同步访问。