我应该同步对干扰器 Next/Publish 方法的访问吗?

jav*_*red 2 c# disruptor-pattern

我没有提供完整的列表,因为下面的代码对于那些熟悉 Disruptor 的人来说已经足够了。问题是调用NextPublish方法是否是线程安全的。下面的例子中哪一个是正确的?请注意,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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

例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);
    }
Run Code Online (Sandbox Code Playgroud)

例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);
    }
Run Code Online (Sandbox Code Playgroud)

小智 5

我是disruptor-net 的作者。

破坏者是一个并发集合,因此一旦正确配置,您就不必应用任何锁定。在您的情况下,您应该使用 MultiThreadedClaimStrategy 初始化 RingBuffer,因为您有多个生产者并使用示例 3 发布到环形缓冲区。

也就是说,我不鼓励在生产代码中使用disruptor-net,我不久前在业余时间移植了它,并且还没有在生产代码中使用它,这需要进一步的测试。

也就是说,.NET 并发队列比 Java 队列快得多,因此我建议使用 ConcurrentQueue 作为 disrutpor 或 BlockingCollection 的替代品,它提供的语义非常接近 Disruptor。