我没有提供完整列表,因为下面的代码对于那些熟悉破坏者的人来说已经足够了。
问题是调用Next
和Publish
方法是否是线程安全的。在下面的例子中,什么是正确的?请注意,Attach
可以同时从不同的线程调用。我有多个消费者。
例1。锁定一切:
private object attachLock = new object();
// can be called from parallel threads
public void Attach(OrdersExecutor oe)
{
lock (attachLock)
{
long sequenceNo = ringBuffer.Next();
ringBuffer[sequenceNo].Value = oe;
ringBuffer.Publish(sequenceNo);
}
}
例2。锁定下一个:
private object attachLock = new object();
// can be called from parallel threads
public void Attach(OrdersExecutor oe)
{
long sequenceNo;
lock (attachLock)
{
sequenceNo = ringBuffer.Next();
}
ringBuffer[sequenceNo].Value = oe;
ringBuffer.Publish(sequenceNo);
}
示例3。没有锁
private object attachLock = new object();
// can be called from parallel threads
public void Attach(OrdersExecutor oe)
{
long sequenceNo = ringBuffer.Next();
ringBuffer[sequenceNo].Value = oe;
ringBuffer.Publish(sequenceNo);
}
答案 0 :(得分:4)
我是disruptor-net的作者。
disruptor是一个并发集合,因此一旦配置正确,您不必应用任何锁定。在您的情况下,您应该使用MultiThreadedClaimStrategy初始化RingBuffer,因为您有多个生成器并使用示例3发布到环形缓冲区。
那就是说,我不鼓励在生产代码中使用disruptor-net,我暂时把它移植到我的业余时间并且没有在生产代码中使用它,它需要进一步测试。
也就是说,.NET并发队列明显快于Java队列,因此我建议使用ConcurrentQueue作为disrutpor的替代方法,或者使用BlockingCollection提供与Disruptor非常接近的语义。
答案 1 :(得分:1)
简而言之,Next()
和Publish()
的实施基于Interlocked
静态类。因此,确保代码设计是线程安全的。它看起来是线程安全的,并且像一个人一样。但它是否安全?我不知道。
这个项目似乎不太活跃,并且落后于Java API。有些测试失败(在Mono上),有些功能根本没有测试(WorkerPool)。小心使用。
我已经邮寄了作者邀请他发表评论,让我们等待他的澄清。