我需要创建一个通用队列,可以排队我的多个生产者,并由多个消费者出队。线程安全队列<t>在C#
我希望系统至少在系统更改期间尝试两次操作,所以如果进程线程失败,现在标记的qBit会再次排队,然后再次处理时,执行该操作的线程会知道另一个线程已经尝试过这个操作一次,如果失败了,请将这个特定的一个发送到修复队列以供外部干预。
所以....对于实际问题,我意识到队列的状态可能会在contains()和队列操作之间改变,就像套接字检查只是错误控制的一种形式,而不是替代。我这样做是因为两个生产者线程可能会抛出一个错误,当两个相同的id(由GUID标识)试图排队什么,否则将是qBit的不同对象实例。
问题是,这是一个合理的实现?我不能看到它永远陷入僵局,因为所有的方法都会返回,无论处理qBit的结果如何,这可以让我在某种程度上防止其中一些。
想法和/或第二组眼睛吗?
public class tsQueue<t>
{
object syncLock = new object();
private Queue<qBit<t>> Q = new Queue<qBit<t>>();
List<t> contents = new List<t>();
public qBit<t> deQueue()
{
lock (syncLock)
{
qBit<t> pop = Q.Dequeue();
contents.Remove(pop.item);
return pop;
}
}
public void enQueue(qBit<t> push)
{
lock (syncLock)
{
contents.Add(push.item);
Q.Enqueue(push);
}
}
public bool contains(t check) {
lock (syncLock)
{
return contents.Contains(check);
}
}
public class qBit<t>
{
public bool flag { get; set; }
private t _item;
public t item { get { return _item; } }
public qBit(t item)
{
this._item = item;
}
}
}
你看过'ConcurrentQueue'吗? –
phoog
2015-03-02 21:13:57
这看起来线程安全给我。 @phoog我想用这两种方法对解决方案进行基准测试。根据我的经验,有时手动锁定非线程安全对象实际上比使用线程安全的对象(即使用Queue vs ConcurrentQueue)更快。但是,我认为使用这两者之间的选择必须是特定于应用程序的。 – phishfordead 2015-03-02 21:17:50
@phishfordead如果性能是一个问题,是的,应该基准和考虑哪种解决方案更快。图书馆解决方案通常比手动解决方案慢;图书馆需要逻辑来处理可能与所讨论的用例无关的条件。但是,库代码也可能比手动代码更好地测试,更不用说更彻底的思考了。因此,应该将衡量更好性能的好处(如果实际上基准测试表现出更好的性能)与测试和调试的成本进行权衡,以确保正确性。 – phoog 2015-03-02 21:22:44