Disruptor浅析

这里使用的是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 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 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处理产生事件对象。


你可能感兴趣的:(Java)