LMAX Disruptor Producer在消费者完成阅读之前错误地环绕+覆盖

时间:2018-05-27 00:28:01

标签: java blocking producer-consumer disruptor-pattern lmax

我最近被介绍给LMAX Disruptor,并决定尝试一下。感谢开发人员,设置快速而轻松。但是,如果有人可以帮助我,我想我遇到了一个问题。

问题: 我被告知,当制作人发布该事件时,它应该阻止,直到消费者有机会在回合之前检索它。我在消费者方面有一个序列障碍,我可以确认,如果生产者没有发布数据,消费者的waitFor调用将会阻止。但是,生产者似乎没有受到任何方式的监管,只会环绕并覆盖环形缓冲区中未处理的数据。

我有一个生产者作为在不同线程上运行的可运行对象。

public class Producer implements Runnable {
    private final RingBuffer<Event> ringbuffer;
    public Producer(RingBuffer<Event> rb) {
        ringbuffer = rb;
    }
    public void run() {
           long next = 0L;
           while(true) {
               try {
                   next = ringbuffer.next();
                   Event e = ringbuffer.get(next);
                   ... do stuff...
                   e.set(... stuff...);
               }
               finally {
                   ringbuffer.publish(next);
               }
           }
    }
}

我有一个消费者在主线程上运行。

public class Consumer {
     private final ExecutorService exec;
     private final Disruptor<Event> disruptor;
     private final RingBuffer<Event> ringbuffer;
     private final SequenceBarrier seqbar;
     private long seq = 0L;

     public Consumer() {
         exec = Executors.newCachedThreadPool();
         disruptor = new Disruptor<>(Event.EVENT_FACTORY, 1024, Executors.defaultThreadFactory());
         ringbuffer = disruptor.start();
         seqbar = ringbuffer.newBarrier();

         Producer producer = new Producer(ringbuffer);
         exec.submit(producer);
    }

    public Data getData() {
         seqbar.waitFor(seq);
         Event e = ringbuffer.get(seq);
         seq++;
         return e.get();
    }
}

最后,我像这样运行代码:

public class DisruptorTest {
     public static void main(String[] args){
         Consumer c = new Consumer();
         while (true) {
             c.getData();
             ... Do stuff ...
         }
}

1 个答案:

答案 0 :(得分:0)

您需要向ringBuffer添加一个门控序列(df['std'] = df['Close'].rolling(n).std() ),此序列必须更新您的消费者所在的位置。

您可以使用EventHandler接口实现事件处理,并使用内置序列附带提供的BatchEventProcessor(com.lmax.disruptor.Sequence

这是一个完全有效的例子

com.lmax.disruptor.BatchEventProcessor.BatchEventProcessor