Disruptor并发框架

来源:互联网 发布:出货数据怎么做模板 编辑:程序博客网 时间:2024/05/16 16:15

结构

Disruptor实现了”队列”的功能,应用场景是”生产者-消费者”模型。一般而言,当需要在两个独立的处理线程之间交换数据时,就可以使用Disruptor。
特点:

  1. 同一个“事件”可以有多个消费者,消费者之间可以并行处理,也可以相互依赖形成处理的先后次序。
  2. 预分配用于存储事件内容的内存空间。
Disruptor

通过顺序递增的序号来编号管理通过其进行交换的数据(事件),对数据(事件)的处理过程总是沿着序号递增的顺序处理。
RingBuffer,环形缓冲区,负责对通过Disruptor进行交换的数据进行存储和更新。RingBuffer大小一般为2的N次方。

Disruptor<xxxEvent> disruptor = new Disruptor<xxxEvent>(eventFactory, ringBufferSize, executor, ProducerType.SINGLE,new YieldingWaitStrategy());

Event/EventFactory

生产者和消费者之间进行交换的数据称为事件。数据通常表示为一个类,通过实现EventFactory<xxxEvent>接口的EventFactory来构造事件。Disruptor通过EventFactory在RingBuffer中预创建Event的实例。一个Event实例在RingBuffer上表现为一个数据槽,生产者发布事件前,先从RingBuffer获得一个Event实例(下一个可以写入事件的序号),然后往Event实例中填充数据,并发布到RingBuffer中。事件只有在提交之后才会通知EventProcessor进行处理。

RingBuffer<xxxEvent> ringBuffer = disruptor.getRingBuffer();
long sequence = ringBuffer.next();//请求下一个事件序号;
try {
xxxEvent event = ringBuffer.get(sequence);//获取该序号对应的事件对象;
long data = 5;//获取要通过事件传递的业务数据;
event.set(data);
} finally{
ringBuffer.publish(sequence);//发布事件;
}

最后的ringBuffer.publish方法必须包含在finally中以确保得到调用(如果发生异常也要调用publish)。如果某个请求的 sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。

EventHandler

事件处理接口,是Consumer的真正实现。通过实现接口EventHandler<XXXEvent>定义事件处理的具体实现。

EventHandler<xxxEvent> eventHandler = new xxxEventHandler();
disruptor.handleEventsWith(eventHandler);

Disruptor通过concurrent.ExecutorService提供的线程来执行Consumer的事件处理。
带参数的发布方式:

RingBuffer<xxxEvent> ringBuffer = disruptor.getRingBuffer();
class Translator implements EventTranslatorOneArg<xxxEvent, T>{
@Override
public void translateTo(xxxEvent event, long sequence, T data) {
event.set(data);
}
}
Translator TRANSLATOR =new Translator();
T data=value;
ringBuffer.publishEvent(TRANSLATOR,data);

接口EventHandler的重载方法参数中sequence是事件在ringbuffer中的序列号,boolean endofBatch表示该事件是否为ringbuffer中的最后一个事件。

WaitStrategy

定义Consumer等待下一个事件的策略。Disruptor提供了多个实现:BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy。

使用流程非常简单:
初始化->启动消费者线程->生产者进程发布事件到disruptor。

1 0
原创粉丝点击