Disruptor简介
Disruptor是一个高性能的线程间消息传递库,类似java中的BlockingQUeue队列,也可简单的理解为高性能的“生产者-消费者”模型,具有以下特点。
环形数据结构:预告分配内存,复用数据中的对象,减少GC回收。无锁设计:基于CAS机制实现线程同步,减少了线程间不必要的上下文切换开销。消除伪共享:如果两个不同的并发变量位于同一个缓存行,则在并发情况下,会互相影响到彼此的缓存有效性,进而影响到性能,这叫着‘伪共享’。为每个对象填充一个序号从而确保各自独占一个缓存行。
Disruptor基本组件
RingBuffer:Disruptor底层数据结构实现,核心类,是线程间交换数据的中转地;Sequencer:序号管理器,负责消费者/生产者各自序号、序号栅栏的管理和协调;Sequence:序号,声明一个序号,用于跟踪ringbuffer中任务的变化和消费者的消费情况;SequenceBarrier:序号栅栏,管理和协调生产者的游标序号和各个消费者的序号,确保生产者不会覆盖消费者未来得及处理的消息,确保存在依赖的消费者之间能够按照正确的顺序处理;EventProcessor:事件处理器,监听RingBuffer的事件,并消费可用事件,从RingBuffer读取的事件会交由实际的生产者实现类来消费;它会一直侦听下一个可用的序号,直到该序号对应的事件已经准备好。EventHandler:业务处理器,是实际消费者的接口,完成具体的业务逻辑实现,第三方实现该接口;代表着消费者。Producer:生产者接口,第三方线程充当该角色,producer向RingBuffer写入事件。
Disruptor构建流程
- 定义事件数据模型
- 事件模型工厂类
- 事件处理器(在此实现消费事件)
- 实例化disruptor
- 创建事件生产者
引入pom依赖
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
定义事件数据模型
import lombok.Data;
@Data
public class DisruptorEvent {
private String msg;
}
事件模型工厂类
import com.lmax.disruptor.EventFactory;
public class DisruptorEventFactory implements EventFactory<DisruptorEvent> {
@Override
public DisruptorEvent newInstance() {
return new DisruptorEvent();
}
}
独立消费者事件处理器
- 独立消费者1
import com.lmax.disruptor.EventHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* 独立消费者
*/
@Slf4j
public class DisruptorEventIndHandler0 implements EventHandler<DisruptorEvent>{
private String name;
public DisruptorEventIndHandler0(String name) {
this.name = name;
}
@Override
public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) throws Exception {
//模拟事件处理时间
TimeUnit.MILLISECONDS.sleep(300);
log.info("独立消费者{}: {},sequence:{},endOfBatch:{}", name, disruptorEvent.getMsg(), sequence, endOfBatch);
}
}
- 独立消费者2
import com.lmax.disruptor.EventHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* 独立消费者
*/
@Slf4j
public class DisruptorEventIndHandler1 implements EventHandler<DisruptorEvent>{
private String name;
public DisruptorEventIndHandler1(String name) {
this.name = name;
}
@Override
public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) throws Exception {
//模拟事件处理时间
TimeUnit.MILLISECONDS.sleep(300);
log.info("独立消费者{}: {},sequence:{},endOfBatch:{}", name, disruptorEvent.getMsg(), sequence, endOfBatch);
}
}
- 共同消费者
import com.lmax.disruptor.WorkHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
/**
* 共同消费者
*/
@Slf4j
public class DisruptorEventCommHandler implements WorkHandler<DisruptorEvent> {
private String name;
public DisruptorEventCommHandler(String name) {
this.name = name;
}
@Override
public void onEvent(DisruptorEvent disruptorEvent) throws Exception {
//模拟事件处理时间
TimeUnit.MILLISECONDS.sleep(300);
log.info("共同消费者{} :{}", name, disruptorEvent.getMsg());
}
}
构建生产者
import com.lmax.disruptor.RingBuffer;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DisruptorEventProducer {
private final RingBuffer<DisruptorEvent> ringBuffer;
public DisruptorEventProducer(RingBuffer<DisruptorEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void publish(String msg){
// ringBuffer是个队列,其next方法返回的是下最后一条记录之后的位置,这是个可用位置
long next = ringBuffer.next();
try {
DisruptorEvent event = ringBuffer.get(next);
event.setMsg(msg);
} catch (Exception e) {
log.error("向RingBuffer队列存入数据[{}]出现异常=>{}", msg, e.getStackTrace());
} finally {
ringBuffer.publish(next);
}
}
}
定义抽象类DisruptorService
实例化Disruptor和生产者
import com.abel.demo.disruptor.DisruptorEvent;
import com.abel.demo.disruptor.DisruptorEventFactory;
import com.abel.demo.disruptor.DisruptorEventProducer;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import javax.annotation.PostConstruct;
public abstract class DisruptorService {
/**
* 环形队列缓冲区大小,为测试看效果所以下面设置得小点,生产上应该配置大些
* 必须为2的N次方(能将求模运算转为位运算提高效率)
* 当超过此大小后,再有生产加入时会进行阻塞,
* 直到有消费者处理完,有空位后则继续加入
*/
protected int BUFFER_SIZE = 8;
protected Disruptor<DisruptorEvent> disruptor;
//生产者
private DisruptorEventProducer producer;
@PostConstruct
private void init() {
// 实例化,disruptor-handler- 为线程名
disruptor = new Disruptor<>(new DisruptorEventFactory(), BUFFER_SIZE,
new CustomizableThreadFactory("disruptor-handler-"), ProducerType.SINGLE, new BlockingWaitStrategy());
//抽象方法,子类实现
handleEvents();
// 启动
disruptor.start();
// 实例化生产者
producer = new DisruptorEventProducer(disruptor.getRingBuffer());
}
/**
* 发布事件
* @param value
* @return
*/
public void publish(String value) {
producer.publish(value);
}
public long getCursor() {
return disruptor.getCursor();
}
/**
* 留给子类实现具体的事件消费逻辑
*/
protected abstract void handleEvents();
}
实现抽象类DisruptorService的handleEvents方法
- 独立消费者
import com.abel.demo.disruptor.DisruptorEventIndHandler0;
import com.abel.demo.disruptor.DisruptorEventIndHandler1;
import com.abel.demo.service.DisruptorService;
import org.springframework.stereotype.Service;
@Service
public class DisruptorIndServiceImpl extends DisruptorService {
@Override
protected void handleEvents() {
/**
* 调用handleEventsWith,表示创建的多个消费者,每个都是独立消费的
* 可以定义不同的消费者处理器,也可使用相同的处理器。
* 实际场景中应该多数使用不同的处理器,因为正常来讲独立消费者做的应该是不同的事。
* 所以本例中是定义了两个不同的消费者DisruptorEventIndHandler0和DisruptorEventIndHandler1
*/
disruptor.handleEventsWith(new DisruptorEventIndHandler0("A"), new DisruptorEventIndHandler1("B"));
}
}
- 共同消费者
import com.abel.demo.disruptor.DisruptorEventCommHandler;
import com.abel.demo.service.DisruptorService;
import org.springframework.stereotype.Service;
@Service
public class DisruptorCommServiceImpl extends DisruptorService {
@Override
protected void handleEvents() {
/**
* 调用handleEventsWithWorkerPool,表示创建的多个消费者以共同消费的模式消费;
* 单个消费者时可保证其有序性,多个时无法保证其顺序;
* 或者说每个消费者是有序的,但每个消费者间是并行执行的,所以无法保证整体的有序
* 共同消费者做的应该是同个事,所以本例中只定义了一个共同消费者DisruptorEventCommHandler
*/
disruptor.handleEventsWithWorkerPool(new DisruptorEventCommHandler( "A"),
new DisruptorEventCommHandler( "B"));
}
}
测试
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloApplicationTests {
@Autowired
private DisruptorCommServiceImpl disruptorCommService;
@Autowired
private DisruptorIndServiceImpl disruptorIndService;
/**
* 独立消费者测试
* 生产者生产20条消息,由两个消费者各自独立消费20条,两者加起共40
* @param n
*/
void disruptorIndTest(int n){
disruptorIndService.publish("事件"+n);
log.info("n:{}, 队列数量:{}, 完成:{}", n, disruptorIndService.getCursor());
}
/**
* 共同消费者测试
* 生产者生产20条消息,由两个消费者共同消费,两者加起共20
* @param n
*/
void disruptorCommTest(int n){
disruptorCommService.publish("事件"+n);
log.info("n:{}, 队列数量:{}, 完成:{}", n, disruptorCommService.getCursor());
}
@Test
public void disruptorTest() throws InterruptedException {
for (int i = 0; i < 20; i++) {
disruptorIndTest(i);
// disruptorCommTest(i);
}
log.info("生产者插入结束");
//因为处理消息是异步的,停一会是为了让所有消息处理完成
TimeUnit.SECONDS.sleep(5);
log.info("等待结束");
}
}
- 独立消费者测试结果
- 由下面的结果可以看出,当生产队列达到我们设置的8后,则进行阻塞不再插入。等到有消费者消费后,多出空位才再继续插入。
- 下面表面看到的是一次性插入8条后,消费者才开始处理,造成此现象的原因是因为我们在生产处理事件中加了TimeUnit.MILLISECONDS.sleep(300);,如果把它注释掉重新再运行时可以看到是生产者一边插入,消费者一边处理的
- 生产者发出20条消息,两个独立消费者各自进行消费处理,总数40
- 两个消费者各自处理的顺序是有充的
2022-07-25 12:01:52.617 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:0
2022-07-25 12:01:52.618 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:1
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:2
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:3
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:4
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:5
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:6
2022-07-25 12:01:52.619 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:7
2022-07-25 12:01:52.926 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件0,sequence:0,endOfBatch:true
2022-07-25 12:01:52.926 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件0,sequence:0,endOfBatch:true
2022-07-25 12:01:52.942 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:8
2022-07-25 12:01:53.239 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件1,sequence:1,endOfBatch:false
2022-07-25 12:01:53.239 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件1,sequence:1,endOfBatch:false
2022-07-25 12:01:53.548 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件2,sequence:2,endOfBatch:false
2022-07-25 12:01:53.548 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件2,sequence:2,endOfBatch:false
2022-07-25 12:01:53.860 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件3,sequence:3,endOfBatch:false
2022-07-25 12:01:53.860 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件3,sequence:3,endOfBatch:false
2022-07-25 12:01:54.171 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件4,sequence:4,endOfBatch:false
2022-07-25 12:01:54.171 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件4,sequence:4,endOfBatch:false
2022-07-25 12:01:54.483 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件5,sequence:5,endOfBatch:false
2022-07-25 12:01:54.483 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件5,sequence:5,endOfBatch:false
2022-07-25 12:01:54.796 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件6,sequence:6,endOfBatch:false
2022-07-25 12:01:54.796 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件6,sequence:6,endOfBatch:false
2022-07-25 12:01:55.107 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件7,sequence:7,endOfBatch:true
2022-07-25 12:01:55.107 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件7,sequence:7,endOfBatch:true
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:9
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:10
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:11
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:12
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:13
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:14
2022-07-25 12:01:55.123 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:15
2022-07-25 12:01:55.419 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件8,sequence:8,endOfBatch:true
2022-07-25 12:01:55.419 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件8,sequence:8,endOfBatch:true
2022-07-25 12:01:55.434 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:16
2022-07-25 12:01:55.732 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件9,sequence:9,endOfBatch:false
2022-07-25 12:01:55.732 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件9,sequence:9,endOfBatch:false
2022-07-25 12:01:56.044 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件10,sequence:10,endOfBatch:false
2022-07-25 12:01:56.044 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件10,sequence:10,endOfBatch:false
2022-07-25 12:01:56.355 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件11,sequence:11,endOfBatch:false
2022-07-25 12:01:56.355 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件11,sequence:11,endOfBatch:false
2022-07-25 12:01:56.666 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件12,sequence:12,endOfBatch:false
2022-07-25 12:01:56.666 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件12,sequence:12,endOfBatch:false
2022-07-25 12:01:56.977 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件13,sequence:13,endOfBatch:false
2022-07-25 12:01:56.977 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件13,sequence:13,endOfBatch:false
2022-07-25 12:01:57.289 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件14,sequence:14,endOfBatch:false
2022-07-25 12:01:57.289 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件14,sequence:14,endOfBatch:false
2022-07-25 12:01:57.601 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件15,sequence:15,endOfBatch:true
2022-07-25 12:01:57.601 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件15,sequence:15,endOfBatch:true
2022-07-25 12:01:57.617 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:17
2022-07-25 12:01:57.617 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:18
2022-07-25 12:01:57.617 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:19
2022-07-25 12:01:57.617 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 生产者插入结束
2022-07-25 12:01:57.912 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件16,sequence:16,endOfBatch:true
2022-07-25 12:01:57.912 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件16,sequence:16,endOfBatch:true
2022-07-25 12:01:58.225 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件17,sequence:17,endOfBatch:false
2022-07-25 12:01:58.225 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件17,sequence:17,endOfBatch:false
2022-07-25 12:01:58.536 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件18,sequence:18,endOfBatch:false
2022-07-25 12:01:58.536 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件18,sequence:18,endOfBatch:false
2022-07-25 12:01:58.849 INFO 3832 --- [ handler-2] c.a.d.d.DisruptorEventIndHandler1 : 独立消费者B: 生产者事件19,sequence:19,endOfBatch:true
2022-07-25 12:01:58.849 INFO 3832 --- [ handler-1] c.a.d.d.DisruptorEventIndHandler0 : 独立消费者A: 生产者事件19,sequence:19,endOfBatch:true
2022-07-25 12:02:02.631 INFO 3832 --- [ main] com.abel.demo.HelloApplicationTests : 等待结束
- 共同消费者测试结果
- 生产者发出20条消息,两个共同消费者一起进行消费处理,总数20
- 两个消费者各自处理的顺序是有充的,但总体上是无序的
2022-07-25 12:00:53.198 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:0
2022-07-25 12:00:53.199 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:1
2022-07-25 12:00:53.199 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:2
2022-07-25 12:00:53.199 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:3
2022-07-25 12:00:53.199 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:4
2022-07-25 12:00:53.199 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:5
2022-07-25 12:00:53.200 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:6
2022-07-25 12:00:53.200 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:7
2022-07-25 12:00:53.509 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件0
2022-07-25 12:00:53.509 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件1
2022-07-25 12:00:53.525 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:8
2022-07-25 12:00:53.525 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:9
2022-07-25 12:00:53.823 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件2
2022-07-25 12:00:53.823 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件3
2022-07-25 12:00:53.838 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:10
2022-07-25 12:00:53.838 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:11
2022-07-25 12:00:54.133 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件4
2022-07-25 12:00:54.133 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件5
2022-07-25 12:00:54.149 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:12
2022-07-25 12:00:54.149 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:13
2022-07-25 12:00:54.445 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件6
2022-07-25 12:00:54.445 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件7
2022-07-25 12:00:54.461 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:14
2022-07-25 12:00:54.461 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:15
2022-07-25 12:00:54.757 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件9
2022-07-25 12:00:54.757 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件8
2022-07-25 12:00:54.773 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:16
2022-07-25 12:00:54.773 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:17
2022-07-25 12:00:55.069 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件11
2022-07-25 12:00:55.069 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件10
2022-07-25 12:00:55.085 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:18
2022-07-25 12:00:55.085 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者:19
2022-07-25 12:00:55.085 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 生产者插入结束
2022-07-25 12:00:55.382 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件12
2022-07-25 12:00:55.382 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件13
2022-07-25 12:00:55.692 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件15
2022-07-25 12:00:55.692 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件14
2022-07-25 12:00:56.003 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件17
2022-07-25 12:00:56.003 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件16
2022-07-25 12:00:56.316 INFO 17928 --- [ handler-1] c.a.d.d.DisruptorEventCommHandler : 共同消费者A :生产者事件18
2022-07-25 12:00:56.316 INFO 17928 --- [ handler-2] c.a.d.d.DisruptorEventCommHandler : 共同消费者B :生产者事件19
2022-07-25 12:01:00.098 INFO 17928 --- [ main] com.abel.demo.HelloApplicationTests : 等待结束