1.定义事件与事件工厂
事件(Event)就是通过 Disruptor 进行交换的数据类型。
事件工厂(Event Factory)定义了如何实例化事件(Event),需要实现接口 com.lmax.disruptor.EventFactory<T>。Disruptor 通过EventFactory在 RingBuffer 中预创建 Event 的实例。一个 Event 实例实际上被用作一个“数据槽”,发布者发布前,先从RingBuffer 获得一个Event的实例,然后往Event 实例中填充数据,之后再发布到 RingBuffer 中,之后由Consumer 获得该 Event 实例并从中读取数据。
通过实现接口 com.lmax.disruptor.EventHandler<T> 定义事件处理的具体实现,实际上就是消费者。
Disruptor 定义了 com.lmax.disruptor.WaitStrategy 接口用于抽象Consumer如何等待新事件,这是策略模式的应用。
Disruptor 提供了多个WaitStrategy 的实现,每种策略都具有不同性能和优缺点,根据实际运行环境的 CPU 的硬件特点选择恰当的策略,并配合特定的 JVM 的配置参数,能够实现不同的性能提升。
例如,BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy 等,其中,BlockingWaitStrategy 是最低效的策略,但其对CPU的消耗最小并且在各种不同部署环境中能提供更加一致的性能表现;SleepingWaitStrategy的性能表现跟BlockingWaitStrategy差不多,对CPU的消耗也类似,但其对生产者线程的影响最小,适合用于异步日志类似的场景;YieldingWaitStrategy 的性能是最好的,适合用于低延迟的系统。在要求极高性能且事件处理线数小于CPU逻辑核心数的场景中。
• BlockingWaitStrategy: 对低延迟和吞吐率不像CPU占用那么重要
• BusySpinWaitStrategy: CPU使用率高,低延迟
• LiteBlockingWaitStrategy: BlockingWaitStrategy变种,实验性的
• PhasedBackoffWaitStrategy: Spins, then yields, then waits,不过还是适合对低延迟和吞吐率不像CPU占用那么重要的情况
• SleepingWaitStrategy: spin, then yield,然后sleep(LockSupport.parkNanos(1L))在性能和CPU占用率之间做了平衡。
• TimeoutBlockingWaitStrategy: sleep一段时间。 低延迟。
• YieldingWaitStrategy: 使用spin, Thread.yield()方式
4.发布事件
Disruptor 的事件发布过程是一个两阶段提交的过程:
第一步:先从 RingBuffer 获取下一个可以写入的事件的序号;
第二步:获取对应的事件对象,将数据写入事件对象;
第三部:将事件提交到 RingBuffer;
事件只有在提交之后才会通知 EventProcessor 进行处理;ringBuffer.publish 方法最好包含在 finally中以确保必须得到调用;因为如果某个请求的sequence未被提交,将会堵塞后续的发布操作或者其它的producer。
7.示例2:
运行结果:
事件(Event)就是通过 Disruptor 进行交换的数据类型。
事件工厂(Event Factory)定义了如何实例化事件(Event),需要实现接口 com.lmax.disruptor.EventFactory<T>。Disruptor 通过EventFactory在 RingBuffer 中预创建 Event 的实例。一个 Event 实例实际上被用作一个“数据槽”,发布者发布前,先从RingBuffer 获得一个Event的实例,然后往Event 实例中填充数据,之后再发布到 RingBuffer 中,之后由Consumer 获得该 Event 实例并从中读取数据。
package com.zero.disruptor;
import com.lmax.disruptor.EventFactory;
public class SimpleEvent {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static final EventFactory<SimpleEvent> FACTORY = new EventFactory<SimpleEvent>() {
@Override
public SimpleEvent newInstance() {
return new SimpleEvent();
}
};
}
2. 定义事件处理的具体实现
通过实现接口 com.lmax.disruptor.EventHandler<T> 定义事件处理的具体实现,实际上就是消费者。
package com.zero.disruptor;
import java.util.concurrent.TimeUnit;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
/**
* EventHandlers是BatchEventProcessor要用到的, WorkHandler是WorkerPool要用到的。为简便放在了一起
*/
public class SimpleHandler implements EventHandler<SimpleEvent>,
WorkHandler<SimpleEvent> {
private String handlerName;
public SimpleHandler(String handlerName) {
this.handlerName = handlerName;
}
@Override
// Override---EventHandler
public void onEvent(SimpleEvent event, long sequence, boolean endOfBatch)
throws Exception {
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(handlerName + " before deal : sequence = "
+ sequence + ", Event: " + event.getValue());
event.setValue(event.getValue() + "--" + handlerName);
System.out.println(handlerName + " after deal : "
+ "Event: " + event.getValue());
}
@Override
// Override---WorkHandler
public void onEvent(SimpleEvent event) throws Exception {
// TODO Auto-generated method stub
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(handlerName + " before deal : Event: "
+ event.getValue());
event.setValue(event.getValue() + "--" + handlerName);
System.out.println(handlerName + " after deal : "
+ " Event: " + event.getValue());
}
}
3. 等待策略
Disruptor 定义了 com.lmax.disruptor.WaitStrategy 接口用于抽象Consumer如何等待新事件,这是策略模式的应用。
Disruptor 提供了多个WaitStrategy 的实现,每种策略都具有不同性能和优缺点,根据实际运行环境的 CPU 的硬件特点选择恰当的策略,并配合特定的 JVM 的配置参数,能够实现不同的性能提升。
例如,BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy 等,其中,BlockingWaitStrategy 是最低效的策略,但其对CPU的消耗最小并且在各种不同部署环境中能提供更加一致的性能表现;SleepingWaitStrategy的性能表现跟BlockingWaitStrategy差不多,对CPU的消耗也类似,但其对生产者线程的影响最小,适合用于异步日志类似的场景;YieldingWaitStrategy 的性能是最好的,适合用于低延迟的系统。在要求极高性能且事件处理线数小于CPU逻辑核心数的场景中。
• BlockingWaitStrategy: 对低延迟和吞吐率不像CPU占用那么重要
• BusySpinWaitStrategy: CPU使用率高,低延迟
• LiteBlockingWaitStrategy: BlockingWaitStrategy变种,实验性的
• PhasedBackoffWaitStrategy: Spins, then yields, then waits,不过还是适合对低延迟和吞吐率不像CPU占用那么重要的情况
• SleepingWaitStrategy: spin, then yield,然后sleep(LockSupport.parkNanos(1L))在性能和CPU占用率之间做了平衡。
• TimeoutBlockingWaitStrategy: sleep一段时间。 低延迟。
• YieldingWaitStrategy: 使用spin, Thread.yield()方式
4.发布事件
Disruptor 的事件发布过程是一个两阶段提交的过程:
第一步:先从 RingBuffer 获取下一个可以写入的事件的序号;
第二步:获取对应的事件对象,将数据写入事件对象;
第三部:将事件提交到 RingBuffer;
事件只有在提交之后才会通知 EventProcessor 进行处理;ringBuffer.publish 方法最好包含在 finally中以确保必须得到调用;因为如果某个请求的sequence未被提交,将会堵塞后续的发布操作或者其它的producer。
long seq = 0;
for (int i = 0; i < 20; i++) {
try {
seq = ringBuffer.next();// 占个坑 ,ringBuffer一个可用区块
ringBuffer.get(seq).setValue((long) (Math.random() * 9999));// 给这个区块放入数据
} finally {
ringBuffer.publish(seq);// 发布这个区块的数据使handler(consumer)可见
System.out.println("Producer " + seq);
}
}
Disruptor 还提供另外一种形式的调用来简化以上操作,并确保 publish 总是得到调用。
package com.zero.disruptor;
import java.nio.ByteBuffer;
import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.RingBuffer;
public class SimpleEventProducer {
private final RingBuffer<SimpleEvent> ringBuffer;
public SimpleEventProducer(RingBuffer<SimpleEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
private static final EventTranslatorOneArg TRANSLATOR = new EventTranslatorOneArg<SimpleEvent, String>() {
@Override
public void translateTo(SimpleEvent event, long sequence, String value) {
System.out.println("Producer --- " + sequence + ", event = "
+ value);
event.setValue(value);
}
};
/**
* onData用来发布事件
*
* @param value
*/
public void onData(final String value) {
ringBuffer.publishEvent(TRANSLATOR, value);
}
}
5. 关闭 Disruptor
disruptor.shutdown();//关闭 disruptor,方法会堵塞,直至所有的事件都得到处理;
executor.shutdown();//关闭 disruptor 使用的线程池;如果需要的话,必须手动关闭, disruptor 在 shutdown 时不会自动关闭;
6.示例1:
public static void demo0() throws Exception {
/*
* createSingleProducer创建一个单生产者的RingBuffer,
* 第一个参数叫EventFactory,从名字上理解就是“事件工厂”,其实它的职责就是产生数据填充RingBuffer的区块。
* 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率
* 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略
*/
final RingBuffer<SimpleEvent> ringBuffer = RingBuffer
.createSingleProducer(SimpleEvent.FACTORY, 2,
new SleepingWaitStrategy());
// 创建线程池
ExecutorService executors = Executors.newCachedThreadPool();
// 创建SequenceBarrier
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
// 创建消息处理器 ,消费者
BatchEventProcessor<SimpleEvent> processor1 = new BatchEventProcessor<SimpleEvent>(
ringBuffer, sequenceBarrier, new SimpleHandler(
"EventHandler_01"));
// 传入所有消费者线程的序号,如果只有一个消费者的情况可以省略
ringBuffer.addGatingSequences(processor1.getSequence());
// 把消息处理器提交到线程池
executors.submit(processor1);
// 如果存在多个消费者 那重复执行上面3行代码 把SimpleHandler换成其它消费者类
BatchEventProcessor<SimpleEvent> processor2 = new BatchEventProcessor<SimpleEvent>(
ringBuffer, sequenceBarrier, new SimpleHandler(
"EventHandler_02"));
ringBuffer.addGatingSequences(processor2.getSequence());
executors.submit(processor2);
// 两个消费者会消费一样的事件
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (int i = 0; i < 4; i++) {
producer.onData(String.valueOf(i));
}
processor1.halt();// 通知事件(或者说消息)处理器可以结束了(并不是马上结束!!!)
processor2.halt();
executors.shutdown();// 终止线程
}
运行结果:
Producer --- 0, event = 0
Producer --- 1, event = 1
EventHandler_02 before deal : sequence = 0, Event: 0
EventHandler_02 after deal : Event: 0--EventHandler_02
EventHandler_01 before deal : sequence = 0, Event: 0--EventHandler_02
EventHandler_01 after deal : Event: 0--EventHandler_02--EventHandler_01
EventHandler_02 before deal : sequence = 1, Event: 1
EventHandler_02 after deal : Event: 1--EventHandler_02
EventHandler_01 before deal : sequence = 1, Event: 1--EventHandler_02
EventHandler_01 after deal : Event: 1--EventHandler_02--EventHandler_01
Producer --- 2, event = 2
Producer --- 3, event = 3
EventHandler_01 before deal : sequence = 2, Event: 2
EventHandler_01 after deal : Event: 2--EventHandler_01
EventHandler_02 before deal : sequence = 2, Event: 2--EventHandler_01
EventHandler_02 after deal : Event: 2--EventHandler_01--EventHandler_02
EventHandler_01 before deal : sequence = 3, Event: 3
EventHandler_01 after deal : Event: 3--EventHandler_01
EventHandler_02 before deal : sequence = 3, Event: 3--EventHandler_01
EventHandler_02 after deal : Event: 3--EventHandler_01--EventHandler_02
可以看出,每个event都被处理了,但是先后顺序不同,如果需要有先后顺序,可以采用一下方式:
public static void demo1() throws Exception {
final RingBuffer<SimpleEvent> ringBuffer = RingBuffer
.createSingleProducer(SimpleEvent.FACTORY, 2,
new SleepingWaitStrategy());
ExecutorService executors = Executors.newCachedThreadPool();
SequenceBarrier stepOneSequenceBarrier = ringBuffer.newBarrier();
BatchEventProcessor<SimpleEvent> processor1 = new BatchEventProcessor<SimpleEvent>(
ringBuffer, stepOneSequenceBarrier, new SimpleHandler(
"EventHandler_01"));
executors.submit(processor1);
SequenceBarrier stepTwoSequenceBarrier = ringBuffer
.newBarrier(processor1.getSequence());
BatchEventProcessor<SimpleEvent> processor2 = new BatchEventProcessor<SimpleEvent>(
ringBuffer, stepTwoSequenceBarrier, new SimpleHandler(
"EventHandler_02"));
//processor2消费最慢,所以以processor2的Sequence为阈值
ringBuffer.addGatingSequences(processor2.getSequence());
executors.submit(processor2);
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (int i = 0; i < 4; i++) {
producer.onData(String.valueOf(i));
}
executors.shutdown();// 终止线程
}
运行结果:
Producer --- 0, event = 0
Producer --- 1, event = 1
EventHandler_01 before deal : sequence = 0, Event: 0
EventHandler_01 after deal : Event: 0--EventHandler_01
EventHandler_01 before deal : sequence = 1, Event: 1
EventHandler_01 after deal : Event: 1--EventHandler_01
EventHandler_02 before deal : sequence = 0, Event: 0--EventHandler_01
EventHandler_02 after deal : Event: 0--EventHandler_01--EventHandler_02
EventHandler_02 before deal : sequence = 1, Event: 1--EventHandler_01
EventHandler_02 after deal : Event: 1--EventHandler_01--EventHandler_02
Producer --- 2, event = 2
Producer --- 3, event = 3
EventHandler_01 before deal : sequence = 2, Event: 2
EventHandler_01 after deal : Event: 2--EventHandler_01
EventHandler_01 before deal : sequence = 3, Event: 3
EventHandler_01 after deal : Event: 3--EventHandler_01
EventHandler_02 before deal : sequence = 2, Event: 2--EventHandler_01
EventHandler_02 after deal : Event: 2--EventHandler_01--EventHandler_02
EventHandler_02 before deal : sequence = 3, Event: 3--EventHandler_01
EventHandler_02 after deal : Event: 3--EventHandler_01--EventHandler_02
如果想一个消息只被一个消费者消费呢?
public static void demo2() throws Exception {
final RingBuffer<SimpleEvent> ringBuffer = RingBuffer
.createSingleProducer(SimpleEvent.FACTORY, 4,
new SleepingWaitStrategy());
ExecutorService executors = Executors.newCachedThreadPool();
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
// 创建消息处理器 ,消费者
WorkHandler<SimpleEvent> processor1 = new SimpleHandler("WorkHandler_1");
WorkHandler<SimpleEvent> processor2 = new SimpleHandler("WorkHandler_2");
WorkerPool<SimpleEvent> workerPool = new WorkerPool<SimpleEvent>(
ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(),
processor1, processor2);
ringBuffer.addGatingSequences(workerPool.getWorkerSequences());// 要在workerPool.start(executors);之前
workerPool.start(executors);
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (int i = 0; i < 4; i++) {
producer.onData(String.valueOf(i));
}
workerPool.halt();
executors.shutdown();// 终止线程
}
运行结果:
Producer --- 0, event = 0
Producer --- 1, event = 1
Producer --- 2, event = 2
Producer --- 3, event = 3
WorkHandler_2 before deal : Event: 1
WorkHandler_1 before deal : Event: 0
WorkHandler_1 after deal : Event: 0--WorkHandler_1
WorkHandler_2 after deal : Event: 1--WorkHandler_2
WorkHandler_1 before deal : Event: 2
WorkHandler_2 before deal : Event: 3
WorkHandler_2 after deal : Event: 3--WorkHandler_2
WorkHandler_1 after deal : Event: 2--WorkHandler_1
如果想一个消息被两组消费者消费,但是每组只能有一个消费?
public static void demo3() throws Exception {
final RingBuffer<SimpleEvent> ringBuffer = RingBuffer
.createSingleProducer(SimpleEvent.FACTORY, 4,
new SleepingWaitStrategy());
ExecutorService executors = Executors.newCachedThreadPool();
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
// 创建消息处理器 ,消费者
WorkHandler<SimpleEvent> processor1 = new SimpleHandler("WorkHandler_1");
WorkHandler<SimpleEvent> processor2 = new SimpleHandler("WorkHandler_2");
WorkerPool<SimpleEvent> workerPool = new WorkerPool<SimpleEvent>(
ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(),
processor1, processor2);
ringBuffer.addGatingSequences(workerPool.getWorkerSequences());// 要在workerPool.start(executors);之前
workerPool.start(executors);
// 创建消息处理器 ,消费者
WorkerPool<SimpleEvent> workerPool2 = new WorkerPool<SimpleEvent>(
ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(),
new SimpleHandler("WorkHandler_3"));
ringBuffer.addGatingSequences(workerPool2.getWorkerSequences());// 要在workerPool.start(executors);之前
workerPool2.start(executors);
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (int i = 0; i < 4; i++) {
producer.onData(String.valueOf(i));
}
workerPool.halt();
executors.shutdown();// 终止线程
}
运行结果:
Producer --- 0, event = 0
Producer --- 1, event = 1
Producer --- 2, event = 2
Producer --- 3, event = 3
WorkHandler_2 before deal : Event: 1
WorkHandler_3 before deal : Event: 0
WorkHandler_3 after deal : Event: 0--WorkHandler_3
WorkHandler_1 before deal : Event: 0
WorkHandler_1 after deal : Event: 0--WorkHandler_3--WorkHandler_1
WorkHandler_2 after deal : Event: 1--WorkHandler_2
WorkHandler_2 before deal : Event: 3
WorkHandler_1 before deal : Event: 2
WorkHandler_1 after deal : Event: 2--WorkHandler_1
WorkHandler_2 after deal : Event: 3--WorkHandler_2
WorkHandler_3 before deal : Event: 1--WorkHandler_2
WorkHandler_3 after deal : Event: 1--WorkHandler_2--WorkHandler_3
WorkHandler_3 before deal : Event: 2--WorkHandler_1
WorkHandler_3 after deal : Event: 2--WorkHandler_1--WorkHandler_3
WorkHandler_3 before deal : Event: 3--WorkHandler_2
WorkHandler_3 after deal : Event: 3--WorkHandler_2--WorkHandler_3
7.示例2:
public static void work1() {
ExecutorService executor = Executors.newFixedThreadPool(2);
int ringBufferSize = 2; // RingBuffer 大小,必须是 2 的 N 次方;
// 构造Disruptor
Disruptor<SimpleEvent> disruptor = new Disruptor<SimpleEvent>(
SimpleEvent.FACTORY, ringBufferSize, executor,
ProducerType.SINGLE, new BlockingWaitStrategy());
disruptor.handleEventsWith(new SimpleHandler("BatchEventHandler_01"),
new SimpleHandler("BatchEventHandler_02"));
// 每个EventHandler占用一个线程,如果Executors.newFixedThreadPool(1);会导致阻塞
RingBuffer<SimpleEvent> ringBuffer = disruptor.start();
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (long i = 10; i < 15; i++) {
producer.onData(String.valueOf(i));
}
// 关闭 Disruptor
disruptor.shutdown();// 关闭 disruptor,方法会堵塞,直至所有的事件都得到处理;
executor.shutdown();// 关闭 disruptor 使用的线程池;如果需要的话,必须手动关闭,
// disruptor在shutdown 时不会自动关闭;
}
以上示例,效果等同于demo0。运行结果;
Producer --- 0, event = 10
Producer --- 1, event = 11
BatchEventHandler_02 before deal : sequence = 0, Event: 10
BatchEventHandler_02 after deal : Event: 10--BatchEventHandler_02
BatchEventHandler_01 before deal : sequence = 0, Event: 10
BatchEventHandler_01 after deal : Event: 10--BatchEventHandler_02--BatchEventHandler_01
BatchEventHandler_01 before deal : sequence = 1, Event: 11
BatchEventHandler_01 after deal : Event: 11--BatchEventHandler_01
BatchEventHandler_02 before deal : sequence = 1, Event: 11--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 11--BatchEventHandler_01--BatchEventHandler_02
Producer --- 2, event = 12
Producer --- 3, event = 13
BatchEventHandler_01 before deal : sequence = 2, Event: 12
BatchEventHandler_02 before deal : sequence = 2, Event: 12
BatchEventHandler_02 after deal : Event: 12--BatchEventHandler_02
BatchEventHandler_01 after deal : Event: 12--BatchEventHandler_02--BatchEventHandler_01
BatchEventHandler_02 before deal : sequence = 3, Event: 13
BatchEventHandler_02 after deal : Event: 13--BatchEventHandler_02
BatchEventHandler_01 before deal : sequence = 3, Event: 13--BatchEventHandler_02
BatchEventHandler_01 after deal : Event: 13--BatchEventHandler_02--BatchEventHandler_01
Producer --- 4, event = 14
BatchEventHandler_02 before deal : sequence = 4, Event: 14
BatchEventHandler_02 after deal : Event: 14--BatchEventHandler_02
BatchEventHandler_01 before deal : sequence = 4, Event: 14--BatchEventHandler_02
BatchEventHandler_01 after deal : Event: 14--BatchEventHandler_02--BatchEventHandler_01
可以看出每个SimpleHandler (implements EventHandler)都会处理同一条消息。另外还可以使用类似:
disruptor.handleEventsWith(new SimpleHandler("BatchEventHandler_01"))
.then(new SimpleHandler("BatchEventHandler_02"));
这样的方法来定义依赖关系,比如先执行哪个handler再执行哪个handler。
运行结果:
Producer --- 0, event = 10
Producer --- 1, event = 11
BatchEventHandler_01 before deal : sequence = 0, Event: 10
BatchEventHandler_01 after deal : Event: 10--BatchEventHandler_01
BatchEventHandler_01 before deal : sequence = 1, Event: 11
BatchEventHandler_01 after deal : Event: 11--BatchEventHandler_01
BatchEventHandler_02 before deal : sequence = 0, Event: 10--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 10--BatchEventHandler_01--BatchEventHandler_02
BatchEventHandler_02 before deal : sequence = 1, Event: 11--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 11--BatchEventHandler_01--BatchEventHandler_02
Producer --- 2, event = 12
Producer --- 3, event = 13
BatchEventHandler_01 before deal : sequence = 2, Event: 12
BatchEventHandler_01 after deal : Event: 12--BatchEventHandler_01
BatchEventHandler_01 before deal : sequence = 3, Event: 13
BatchEventHandler_01 after deal : Event: 13--BatchEventHandler_01
BatchEventHandler_02 before deal : sequence = 2, Event: 12--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 12--BatchEventHandler_01--BatchEventHandler_02
BatchEventHandler_02 before deal : sequence = 3, Event: 13--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 13--BatchEventHandler_01--BatchEventHandler_02
Producer --- 4, event = 14
BatchEventHandler_01 before deal : sequence = 4, Event: 14
BatchEventHandler_01 after deal : Event: 14--BatchEventHandler_01
BatchEventHandler_02 before deal : sequence = 4, Event: 14--BatchEventHandler_01
BatchEventHandler_02 after deal : Event: 14--BatchEventHandler_01--BatchEventHandler_02
同样,还可以使用WorkerPool:
public static void work2() {
ExecutorService executor = Executors.newFixedThreadPool(2);
int ringBufferSize = 4; // RingBuffer 大小,必须是 2 的 N 次方;
// 构造Disruptor
Disruptor<SimpleEvent> disruptor = new Disruptor<SimpleEvent>(
SimpleEvent.FACTORY, ringBufferSize, executor,
ProducerType.SINGLE, new BlockingWaitStrategy());
disruptor.handleExceptionsWith(new IgnoreExceptionHandler());
disruptor.handleEventsWithWorkerPool(new SimpleHandler(
"WorkEventHandler_01"),
new SimpleHandler("WorkEventHandler_02"));
RingBuffer<SimpleEvent> ringBuffer = disruptor.start();
// // 获取生产者的位置信息
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
// 生产者
SimpleEventProducer producer = new SimpleEventProducer(ringBuffer);
for (long i = 10; i < 15; i++) {
producer.onData(String.valueOf(i));
}
disruptor.shutdown();
executor.shutdown();
}
运行结果:
Producer --- 0, event = 10
Producer --- 1, event = 11
Producer --- 2, event = 12
Producer --- 3, event = 13
WorkEventHandler_02 before deal : Event: 10
WorkEventHandler_01 before deal : Event: 11
WorkEventHandler_02 after deal : Event: 10--WorkEventHandler_02
WorkEventHandler_01 after deal : Event: 11--WorkEventHandler_01
Producer --- 4, event = 14
WorkEventHandler_02 before deal : Event: 12
WorkEventHandler_02 after deal : Event: 12--WorkEventHandler_02
WorkEventHandler_01 before deal : Event: 13
WorkEventHandler_01 after deal : Event: 13--WorkEventHandler_01
WorkEventHandler_02 before deal : Event: 14
WorkEventHandler_02 after deal : Event: 14--WorkEventHandler_02