![](/img/trans.png)
[英]how to find a Lmax Disruptor diamond(one producer 5 consumer 1 conclude)example?
[英]LMAX Disruptor Producer Incorrectly Wraparound + Overwrite Before Consumer Completes Read
最近向我介紹了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 ...
}
}
您需要將一個選通序列( com.lmax.disruptor.Sequence
)添加到ringBuffer,該序列必須在您的使用者指向的位置進行更新。
您可以使用EventHandler接口並使用提供的內置序列附帶的BatchEventProcessor( com.lmax.disruptor.BatchEventProcessor.BatchEventProcessor
)實現事件處理
這是一個完整的示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.lmax.disruptor.BatchEventProcessor;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.dsl.Disruptor;
public class Main {
static class Event {
int id;
}
static class Producer implements Runnable {
private final RingBuffer<Event> ringbuffer;
public Producer(RingBuffer<Event> rb) {
ringbuffer = rb;
}
@Override
public void run() {
long next = 0L;
int id = 0;
while (true) {
try {
next = ringbuffer.next();
Event e = ringbuffer.get(next);
e.id = id++;
} finally {
ringbuffer.publish(next);
}
}
}
}
static class Consumer {
private final ExecutorService exec;
private final Disruptor<Event> disruptor;
private final RingBuffer<Event> ringbuffer;
private final SequenceBarrier seqbar;
private BatchEventProcessor<Event> processor;
public Consumer() {
exec = Executors.newCachedThreadPool();
disruptor = new Disruptor<>(() -> new Event(), 1024, Executors.defaultThreadFactory());
ringbuffer = disruptor.start();
seqbar = ringbuffer.newBarrier();
processor = new BatchEventProcessor<Main.Event>(
ringbuffer, seqbar, new Handler());
ringbuffer.addGatingSequences(processor.getSequence());
Producer producer = new Producer(ringbuffer);
exec.submit(producer);
}
}
static class Handler implements EventHandler<Event> {
@Override
public void onEvent(Event event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("Handling event " + event.id);
}
}
public static void main(String[] args) throws Exception {
Consumer c = new Consumer();
while (true) {
c.processor.run();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.