定义事件
/**
* 定义event事件:通过Disruptor进行交换的数据类型
* @author hxp
* @create 2020-11-17 17:02
*/
public class StringEvent {
private String value; // 放一个字符串数据
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
定义事件工厂
/**
* 定义事件工厂
* @author hxp
* @create 2020-11-17 17:04
*/
public class StirngEventFactory implements EventFactory<StringEvent> {
@Override
public StringEvent newInstance() {
return new StringEvent();
}
}
消费者 1
对于独立消费的消费者,应当实现EventHandler接口
/**
* 消费者 ----定义事件的具体实现
* @author hxp
* @create 2020-11-17 17:06
*/
public class StringEventHandler implements EventHandler<StringEvent> {
@Override
public void onEvent(StringEvent stringEvent, long sequence, boolean endOfBatch) throws Exception {
// 实际项目中的处理具体的业务逻辑
// if(stringEvent.getValue().equalsIgnoreCase("2")){
// throw new Exception(Thread.currentThread().getName()+"终止整个任务");
// }else {
// }
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"消费者:"+stringEvent.getValue()+ "---> sequence="+sequence+ "---> endOfBatch="+endOfBatch);
}
}
消费者 2
对于不重复消费的消费者,应当实现WorkHandler接口。
/**
* 消费者 ----定义事件的具体实现 不会重复消费
* @author hxp
* @create 2020-11-17 17:06
*/
public class StringWorkHandler implements WorkHandler<StringEvent> {
@Override
public void onEvent(StringEvent event) throws Exception {
// 实际项目中的处理具体的业务逻辑
if(event.getValue().contains("main6")){
// Thread.sleep(15*1000);
throw new Exception(System.currentTimeMillis()+Thread.currentThread().getName()+"终止整个任务");
}else {
System.out.println(System.currentTimeMillis()+Thread.currentThread().getName()+"消费者消费数据"+event.getValue());
}
Thread.sleep(10);
}
}
生产者
/**生产者
* @author hxp
* @create 2020-11-17 17:11
*/
public class StringEventProducer {
// 核心类:环形数组
public final RingBuffer<StringEvent> ringBuffer;
// 构造方法初始化环形数组
public StringEventProducer(RingBuffer<StringEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
/**
* 生产事件(数据)的方法
* 其实就是往环形数组里面放数据
* @param data
*/
public void publish(String data){
// 1 从ringBuffer里面获取下一个序号,也就是我们要放置数据的位置
long sequence = ringBuffer.next();
try {
// 2 取出空的事件队列
StringEvent stringEvent = ringBuffer.get(sequence);
// 3 往事件队列里面放数据
stringEvent.setValue(data);
} finally {
// 4 发布事件(数据)
ringBuffer.publish(sequence);
}
}
}
启动测试类
一个生产者,多个消费者
public class StringEventTest {
public static void main(String[] args) {
Integer consumerThread = 5;
Integer count= 100000;
System.out.println("消费线程数:"+consumerThread);
System.out.println("生产事件数:"+count);
// 事件工厂
StirngEventFactory stringEventFactory = new StirngEventFactory();
// 环形数组的长度最好是2的n次方
int ringBufferSize = 2<<8;
// 线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();
Thread thread = Thread.currentThread();
LocalTime start = LocalTime.now();
System.out.println("开始="+start);
// 创建Disruptor
Disruptor<StringEvent> disruptor = new Disruptor<>(
stringEventFactory, // 事件(数据)工厂
ringBufferSize, // 环形数组的大小
threadFactory, // 线程工厂
ProducerType.SINGLE, // 单个生产者
new YieldingWaitStrategy()); // 当环形数组满的时候的等待策略
// 设置异常处理机制
disruptor.setDefaultExceptionHandler(new ExceptionHandler<StringEvent>() {
@Override
public void handleEventException(Throwable ex, long sequence, StringEvent event) {
if (ex.toString().contains("终止整个任务")) {
System.out.println(ex);
}
}
@Override
public void handleOnStartException(Throwable ex) {
}
@Override
public void handleOnShutdownException(Throwable ex) {
}
});
/**
* 1. 对于某一条消息m,
* handleEventsWith方法返回的EventHandlerGroup,Group中的每个消费者都会对m进行消费,各个消费者之间不存在竞争。
* handleEventsWithWorkerPool方法返回的EventHandlerGroup,Group的消费者对于同一条消息m不重复消费;
* 也就是,如果c0消费了消息m,则c1不再消费消息m。
*
* 2. 传入的形参不同。
* 对于独立消费的消费者,应当实现EventHandler接口。
* 对于不重复消费的消费者,应当实现WorkHandler接口。
*/
// 连接消费端方法 会重复消费
// StringEventHandler[] eventHandlers = new StringEventHandler[consumerThread];
// for (int i = 0; i < eventHandlers.length; i++) {
// eventHandlers[i] = new StringEventHandler();
// }
// disruptor.handleEventsWith(eventHandlers);
// 连接消费端方法 不会重复消费
WorkHandler[] workHandlers = new WorkHandler[consumerThread];
for (int i = 0; i < workHandlers.length; i++) {
workHandlers[i] = new StringWorkHandler();
}
disruptor.handleEventsWithWorkerPool(workHandlers);
// 启动消费者,先启动消费者再启动生产者
disruptor.start();
// 创建生产者
RingBuffer<StringEvent> ringBuffer = disruptor.getRingBuffer();
StringEventProducer producer = new StringEventProducer(ringBuffer);
for (int i = 0; i < count; i++) {
// 生产事件(数据)
producer.publish(thread.getName()+i);
}
// 关闭
disruptor.shutdown();
}
}