disruptor 两种消费方式
基于 3.4.x
disruptor 有两种消费方式:
- 广播式(一个消息被每个消费者都会消费一次,并可以处理依赖任务
A->B
) - 仅消费一次(选择其中一个消费者被消费)
依赖
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
广播式(一个消息被每个消费者都会消费一次)
public class DisruptorTest {
@Data
public static class UEvent {
private String name;
}
public static void main(String[] args) throws InterruptedException {
multiCastPublish();
}
/**
* 广播式
* @throws InterruptedException
*/
private static void multiCastPublish() throws InterruptedException {
int bufferSize = 1024;
Disruptor<UEvent> disruptor = new Disruptor<>(UEvent::new, bufferSize, DaemonThreadFactory.INSTANCE,
ProducerType.MULTI,
new BlockingWaitStrategy());
disruptor.handleEventsWith(new EventHandler<UEvent>() {
@Override
public void onEvent(UEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("handler1 execute: " + JSON.toJSONString(event));
}
});
disruptor.handleEventsWith(new EventHandler<UEvent>() {
@Override
public void onEvent(UEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("handler2 execute: " + JSON.toJSONString(event));
}
});
disruptor.start();
RingBuffer<UEvent> ringBuffer = disruptor.getRingBuffer();
String name = "test";
ringBuffer.publishEvent(((event, sequence, data) -> event.setName(data)), name);
TimeUnit.SECONDS.sleep(5);
}
}
结果:
handler1 execute: {"name":"test"}
handler2 execute: {"name":"test"}
可以发现 handler1和hander2都消费了这个消息
仅消费一次(选择其中一个消费者被消费)
public static class MWorkerHandler implements WorkHandler<UEvent> {
@Override
public void onEvent(UEvent event) throws Exception {
System.out.println(Thread.currentThread().getName() + " execute " + JSON.toJSONString(event));
}
}
private static void singleCast() throws InterruptedException {
int bufferSize = 1024;
Disruptor<UEvent> disruptor = new Disruptor<>(UEvent::new, bufferSize, DaemonThreadFactory.INSTANCE,
ProducerType.MULTI,
new BlockingWaitStrategy());
RingBuffer<UEvent> ringBuffer = disruptor.getRingBuffer();
MWorkerHandler[] handlers = new MWorkerHandler[4];
for (int i = 0; i < 4; i++) {
handlers[i] = new MWorkerHandler();
}
disruptor.handleEventsWithWorkerPool(handlers);
disruptor.start();
String name = "test";
ringBuffer.publishEvent(((event, sequence, data) -> event.setName(data)), name);
name = "heloo";
ringBuffer.publishEvent(((event, sequence, data) -> event.setName(data)), name);
TimeUnit.SECONDS.sleep(5);
}
结果:
Thread-0 execute {"name":"test"}
Thread-1 execute {"name":"heloo"}
可以发现,一个消息只会被一个消费者消费