参考文章:https://www.yuque.com/simonalong/jishu/qhdcb2

依赖

1
2
3
4
5
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>

实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class EventInfoServiceImpl {

private Disruptor<EventInfoAndBack> applyDisruptor;
private RingBuffer<EventInfoAndBack> applyQueue;

@GrpcClient("grpc-server")
private EventInfoServiceGrpc.EventInfoServiceFutureStub eventInfoServiceFutureStub;

public EventInfoServiceImpl() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(7, 7, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1));
this.applyDisruptor = DisruptorBuilder.newInstance(EventInfoAndBack.class).setRingBufferSize(1024).setEventFactory(new EventInfoFactory()).setExecutor(executor).setProducerType(ProducerType.MULTI).setWaitStrategy(new BlockingWaitStrategy()).build();
this.applyDisruptor.handleEventsWithWorkerPool(new EventInfoWorkHandler("1"),new EventInfoWorkHandler("2"),new EventInfoWorkHandler("3"));
this.applyDisruptor.handleEventsWith(new EventInfoHandler("1"), new EventInfoHandler("2"));
this.applyDisruptor.handleEventsWithWorkerPool(new EventInfoWorkHandler("4"),new EventInfoWorkHandler("5"));
this.applyDisruptor.setDefaultExceptionHandler(new FatalExceptionHandler());
applyQueue = applyDisruptor.start();
}

public EventInfoResponse sendEventInfoMessage(String data) {
EventInfoMessage eventInfoMessage = EventInfoMessage.newBuilder().setMsg(data).build();
AtomicReference<EventInfoResponse> eventInfoResponse = new AtomicReference<>();
for (int i = 0; i < 10; i++) {
applyQueue.publishEvent((event, sequence) -> {
event.eventInfoMessage = eventInfoMessage;
event.back = eventInfoResponse::set;
});
}
while (eventInfoResponse.get() == null){

}
return eventInfoResponse.get();
}

private class EventInfoAndBack {
EventInfoMessage eventInfoMessage;
Back<EventInfoResponse> back;

public EventInfoMessage getEventInfoMessage() {
return eventInfoMessage;
}

public void setEventInfoMessage(EventInfoMessage eventInfoMessage) {
this.eventInfoMessage = eventInfoMessage;
}

public Back<EventInfoResponse> getBack() {
return back;
}

public void setBack(Back<EventInfoResponse> back) {
this.back = back;
}
}

private class EventInfoFactory implements EventFactory<EventInfoAndBack> {
@Override
public EventInfoAndBack newInstance() {
return new EventInfoAndBack();
}
}

private class EventInfoHandler implements EventHandler<EventInfoAndBack> {

private String str;

public EventInfoHandler(String str) {
this.str = str;
}

@Override
public void onEvent(EventInfoAndBack eventInfo, long l, boolean b) throws Exception {
System.out.println("event-"+str+":"+Thread.currentThread().getName());
ListenableFuture<EventInfoResponse> response = eventInfoServiceFutureStub.sendMessageEvent(eventInfo.getEventInfoMessage());
eventInfo.back.run(response.get());
}
}

private class EventInfoWorkHandler implements WorkHandler<EventInfoAndBack> {

private String str;

public EventInfoWorkHandler(String str) {
this.str = str;
}

@Override
public void onEvent(EventInfoAndBack eventInfo) throws Exception {
System.out.println("work-"+str+":"+Thread.currentThread().getName());
ListenableFuture<EventInfoResponse> response = eventInfoServiceFutureStub.sendMessageEvent(eventInfo.getEventInfoMessage());
eventInfo.back.run(response.get());
}
}

private interface Back<T> {
void run(T t);
}

}

Disruptor的几个重要的参数:

  1. ringBufferSize:可以理解为环的大小,也就是队列最大容量
  2. eventFactory:参数工厂,需要实现com.lmax.disruptor.EventFactory接口,Disruptor维护对象的生产工厂,队列中的对象通过这个工厂获取
  3. executor:java.util.concurrent.Executor执行器,具体消费者的执行器,Disruptor默认实现了com.lmax.disruptor.dsl.BasicExecutor类,如果只传入线程工厂,就会使用此类,也可以使用其他的执行器,比如代码中使用的就是线程池
  4. producerType:生产模式,由com.lmax.disruptor.dsl.ProducerType枚举控制
    1. SINGLE:单生产者模式,com.lmax.disruptor.SingleProducerSequencer,适用于单线程
    2. MULTI:多生产者模式,对应com.lmax.disruptor.MultiProducerSequencer,适用于多线程,主要区别在于,多生产者模式会使用到cas获取下一个序列,可以无锁解决并发问题,单生产者模式在多线程下可能会出现序列冲突问题
  5. waitStrategy:等待策略,com.lmax.disruptor.WaitStrategy接口控制,即消费者在没有事件需要处理时,如和等待新事件,下面是几个实现类,从上到下,更加轻量
    1. BlockingWaitStrategy:阻塞等待,有新的事件,会被唤醒,调用java.util.concurrent.locks.Condition#await()方法
    2. SleepingWaitStrategy:自旋让渡加休眠等待,每自旋一段时间,就会尝试调用Thread.yield方法让渡cpu资源,再休眠一段时间再自旋等待
    3. YieldingWaitStrategy:自旋让渡,每自旋一段时间,就会尝试调用Thread.yield方法让渡cpu资源,但不会像上者一样休眠等待
    4. BusySpinWaitStrategy:自旋等待,只会不断自旋,不会让渡cpu资源,更不会等待

上面几个参数,大部分其实是RingBuffer类的参数,具体可参考是Disruptor类的构造方法

Disruptor几个重要的方法

  1. handleEventsWith(EventHandler<? super T>… handlers):配置Disruptor的事件处理类,我们编写的事件处理类需要实现EventHandler接口,可以通过此方法一次配置多个事件处理者,也可以多次调用这个方法配置,无论如何配置的,当生产者推送一个事件,所有事件处理者都会收到并处理
  2. handleEventsWithWorkerPool(WorkHandler… workHandlers):配置Disruptor工作处理类,工作处理类与事件处理类的区别在于,通过调用一次handleEventsWithWorkerPool方法配置的多个WorkHandler,而已理解为一个工作组,当有事件推送时,一个工作组中只有一个工作处理者能接收到事件
  3. setDefaultExceptionHandler(ExceptionHandler<? super T> exceptionHandler):配置异常处理类,Disruptor提供了几个默认的实现类,也可以自己实现

本站总访问量:次本站总访问数:人
本站由 Peng Tong 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。