Disruptor github地址为:https : //github.com/LMAX-Exchange/disruptor
我对其进行了一个简单的测试,如下所示:
public class DisruptorMain { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) throws Exception { class Element { private int value; public int get() { return value; } public void set(int value) { this.value = value; } } ThreadFactory threadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "simpleThread"); } }; EventFactory<Element> factory = new EventFactory<Element>() { @Override public Element newInstance() { return new Element(); } }; EventHandler<Element> handler = new EventHandler<Element>() { @Override public void onEvent(Element element, long sequence, boolean endOfBatch) { try { Thread.sleep(1000 * sequence); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Element: " + element.get()); } }; BlockingWaitStrategy strategy = new BlockingWaitStrategy(); int bufferSize = 4; Disruptor<Element> disruptor = new Disruptor(factory, bufferSize, threadFactory, ProducerType.SINGLE, strategy); disruptor.handleEventsWith(handler); disruptor.start(); RingBuffer<Element> ringBuffer = disruptor.getRingBuffer(); for (int l = 0; l < 8; l++) { long sequence = ringBuffer.next(); System.out.println("sequence:" + sequence); try { Element event = ringBuffer.get(sequence); event.set(l); } finally { ringBuffer.publish(sequence); } } } }
结果是:序列:0序列:1序列:2序列:3元素:0元素:1元素:2元素:3序列:4序列:5序列:6序列:7元素:4元素:5元素:6元素:7
在测试中,我定义了一个4的环形缓冲区,我有一个生产者为其创建8个任务,我的问题是,当生产者将4个任务放入环形缓冲区时,使用者开始从环形缓冲区中获取任务要正常工作,在任务1完成后,环形缓冲区应该为任务5提供一个空白空间,但是结果表明,只有在环形缓冲区中所有任务都完成后,环形缓冲区才能接受新任务,为什么?
这是因为Disruptor将在事件处理程序中进行批处理。如果事件处理程序速度慢或环形缓冲区较小,则批处理大小通常可以是环形缓冲区的大小。Disruptor将仅更新该事件处理程序的已处理序列,直到批处理完成为止。这减少了需要对发布者用来确定空间是否可用的序列变量进行的更新次数。如果需要使空间比默认值更早可用,则可以使用SequenceReportingEventHandler来实现。
public class MyEventHandler implements SequenceReportingEventHandler<Element> { Sequence processedSequence; public void setSequenceCallback(Sequence s) { processedSequence = s; } public void onEvent(Element e, long sequence, boolean endOfBatch) { // Do stuff processedSequence.set(sequence); } }