这里使用的是Disruptor3.3版本
- import com.lmax.disruptor.dsl.Disruptor;
- import com.lmax.disruptor.RingBuffer;
- import java.nio.ByteBuffer;
- import java.util.concurrent.Executor;
- import java.util.concurrent.Executors;
- public class LongEventMain
- {
- public static void main(String[] args) throws Exception
- {
- // Executor that will be used to construct new threads for consumers
- Executor executor = Executors.newCachedThreadPool(); //1
- // The factory for the event
- LongEventFactory factory = new LongEventFactory(); //2
- // Specify the size of the ring buffer, must be power of 2.
- int bufferSize = 1024; //3
- // Construct the Disruptor
- Disruptor<LongEvent> disruptor = new Disruptor<>(factory, bufferSize, executor); //4
- // Connect the handler
- disruptor.handleEventsWith(new LongEventHandler()); //5
- // Start the Disruptor, starts all threads running
- disruptor.start(); //6
- // Get the ring buffer from the Disruptor to be used for publishing.
- RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer(); //7
- LongEventProducer producer = new LongEventProducer(ringBuffer); //8
- ByteBuffer bb = ByteBuffer.allocate(8);
- for (long l = 0; true; l++)
- {
- bb.putLong(0, l);
- producer.onData(bb); //9
- Thread.sleep(1000);
- }
- }
- }
步骤:
1、 创建缓存线程池,用于在6步中执行EventProcessor。
2、 LongEventFactory用于创建LongEvent,使用工厂方法模式。该工厂在RingBuffer被初始化时,在fill中调用,用于初始化RingBuffer的单元。
3、 设置RingBuffer的长度为1024。
4、 创建Disruptor对象,该对象中包含RingBuffer、Executor、ConsumerRepository等属性。
RingBuffer对象初始化时,需要用到EventFactory和Sequencer对象。
EventFactory这里使用的是LongEventFactory,在第2步已经讲到。
Sequencer接口包括MultiProducerSequencer和SingleProducerSequencer两种实现。
根据名称可以看出,MultiProducerSequencer主要是多个生产者线程使用,SingleProducerSequencer是单个生产者线程使用。
通过Sequencer和RingBuffer的接口,可以看出RingBuffer这里使用了一个类似于代理的模式,调用自身的sequencer来完成部分功能。
在RingBuffer中,为了防止伪共享问题,做了一些工作。
在Sequencer的抽象实现类AbstractSequencer中,包括bufferSize、waitStrategy、Sequence类型的cursor和Sequence[]类型的gatingSequences数组。
bufferSize是在第3步中设置过的。
waitStrategy是WaitStrategy接口的对象,通过名称可以确认这是一个策略模式,使用waitFor()和signalAllWhenBlocking()两个方法。
waitFor()方法,用于让EventProcessor(事件的处理器)等待可用的sequence个数,如果没有生产者生成的产品或者依赖的处理队列没有处理完,就会一直等待;一般在SequenceBarrier(这个是什么等下讲到)的waitFor中调用。
signalAllWhenBlocking()方法,用于激活等待的EventProcessor,一般在Sequencer继承的Sequenced接口的publish()方法中使用,当生产者有产出后,会激活等待的EventProcessor。
Sequence类型的cursor是当前Sequencer的游标,Sequence类也做了防止伪共享的工作,使用Sequence类满足在并发条件下,追踪RingBuffer和各个EventProcessor填充和处理单元格位置。
gatingSequences数组可以通过Sequencer的addGatingSequences和removeGatingSequences添加和删除,Sequencer的抽象子类AbstractSequencer使用了AtomicReferenceFieldUpdater.newUpdater方式来保证更新的原子性。这个数组的目的是获取当前包括游标在内最大可用值。
Disruptor中的Executor用于运行ConsumerInfo中的EventProcessor。
Disruptor中的ConsumerRepository里存放着响应用的EventProcessors,即上述Executor运行的。
5、创建EventProcessor,EventProcessor在响应事件时,需要调用EventHandler.onEvent方法。
创建EventProcessor时,可能会用到上面提到的SequenceBarrier,用于绑定依赖的Sequence,一般调用WaitStrategy接口的waitFor()方法来等待队列可用。
生成的EventProcessor会和EventHander、SequenceBarrier一起封装在ConsumerInfo中,存在ConsumerRepository中。
6、更新ConsumerReposity中EventProcessor的Sequence为RingBuffer的游标位置,启动所有EventProcessor线程。
7、获取RingBuffer。
8、创建一个生产者。
9、生成者获取RingBuffer的下一个可用Sequence位置,并将RingBuffer的publish方法,即调用WaitStrategy接口的signalAllWhenBlocking()方法,通知EventProcessor处理产生事件对象。