Disruptor浅析

这里使用的是Disruptor3.3版本

代码

[java]  view plain copy
  1. import com.lmax.disruptor.dsl.Disruptor;  
  2. import com.lmax.disruptor.RingBuffer;  
  3. import java.nio.ByteBuffer;  
  4. import java.util.concurrent.Executor;  
  5. import java.util.concurrent.Executors;  
  6.   
  7. public class LongEventMain  
  8. {  
  9.     public static void main(String[] args) throws Exception  
  10.     {  
  11.         // Executor that will be used to construct new threads for consumers  
  12.         Executor executor = Executors.newCachedThreadPool(); //1  
  13.   
  14.         // The factory for the event  
  15.         LongEventFactory factory = new LongEventFactory();  //2  
  16.   
  17.         // Specify the size of the ring buffer, must be power of 2.  
  18.         int bufferSize = 1024//3  
  19.   
  20.         // Construct the Disruptor  
  21.         Disruptor<LongEvent> disruptor = new Disruptor<>(factory, bufferSize, executor); //4  
  22.   
  23.         // Connect the handler  
  24.         disruptor.handleEventsWith(new LongEventHandler()); //5  
  25.   
  26.         // Start the Disruptor, starts all threads running  
  27.         disruptor.start(); //6  
  28.   
  29.         // Get the ring buffer from the Disruptor to be used for publishing.  
  30.         RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer(); //7  
  31.   
  32.         LongEventProducer producer = new LongEventProducer(ringBuffer);  //8  
  33.   
  34.         ByteBuffer bb = ByteBuffer.allocate(8);  
  35.         for (long l = 0true; l++)  
  36.         {  
  37.             bb.putLong(0, l);  
  38.             producer.onData(bb); //9  
  39.             Thread.sleep(1000);  
  40.         }  
  41.     }  
  42. }  

步骤:

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处理产生事件对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值