我应该同步访问破坏者的“下一个/发布"方法吗? [英] should I synchronize access to disruptor Next/Publish methods?

查看:98
本文介绍了我应该同步访问破坏者的“下一个/发布"方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有提供完整的清单,因为下面的代码对于那些熟悉干扰器的人来说已经足够了. 问题是,调用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);
        }
    }

示例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);
    }

解决方案

我是Disruptor-net的作者.

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

也就是说,我不鼓励在生产代码中使用打扰程序网,我是在业余时间移植它的,并且还没有在生产代码中使用它,这需要进一步的测试.

也就是说,.NET并发队列比Java队列要快得多,因此我建议使用ConcurrentQueue作为Disrutpor或BlockingCollection的替代方法,后者提供了非常类似于Disruptor的语义.

I'm not providing full listing as below code is enough for those who familar with disruptor. The question is if calling Next and Publish methods is thread-safe. Between examples below what would be the correct one? Note that Attach can be called from different threads at the same time. And I have multiple consumers.

Example1. Lock everything:

    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);
        }
    }

Example2. Lock Next:

    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);
    }

Example3. No lock

    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);
    }

解决方案

I'm the author of disruptor-net.

The disruptor is a concurrent collection, so you don't have to apply any locking once configured properly. In your case you should initialize the RingBuffer with a MultiThreadedClaimStrategy since you have multiple producers and use Example 3 to publish to the ring buffer.

That said, I discourage usage of disruptor-net in production code, I ported it a while ago on my spare time and have not used it in production code, it would require further testing.

That said, .NET concurrent queue is significantly faster than Java queues so I would suggest to use ConcurrentQueue as an alternative to the disrutpor, or BlockingCollection which offers a semantic very close to the Disruptor.

这篇关于我应该同步访问破坏者的“下一个/发布"方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆