1、定义事件
事件(Event)就是通过 Disruptor 进行交换的数据类型。

package com.ljq.disruptor;

import java.io.Serializable;

/**
* 定义事件数据,本质是个普通JavaBean
*
* @author jqlin
*/
@SuppressWarnings("serial")
public class LongEvent implements Serializable {
private long value; public LongEvent() {
super();
} public LongEvent(long value) {
super();
this.value = value;
} public long getValue() {
return value;
} public void setValue(long value) {
this.value = value;
} @Override
public String toString() {
return "LongEvent [value=" + value + "]";
} }

2、LongEvent事件生产者

package com.ljq.disruptor;

import com.lmax.disruptor.RingBuffer;

/**
* LongEvent事件生产者,生产LongEvent事件
*
* @author jqlin
*/
public class LongEventProducer {
private final RingBuffer<LongEvent> ringBuffer; public LongEventProducer(RingBuffer<LongEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
} public void produceData(long value) {
long sequence = ringBuffer.next(); // 获得下一个Event槽的下标
try {
// 给Event填充数据
LongEvent event = ringBuffer.get(sequence);
event.setValue(value); } finally {
// 发布Event,激活观察者去消费, 将sequence传递给该消费者
// 注意,最后的 ringBuffer.publish() 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的 sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。
ringBuffer.publish(sequence);
}
}
}

3、LongEvent事件消息者

package com.ljq.disruptor;

import com.lmax.disruptor.WorkHandler;

/**
* LongEvent事件消息者,消息LongEvent事件
*
* @author Administrator
*
*/
public class LongEventConsumer implements WorkHandler<LongEvent> { @Override
public void onEvent(LongEvent event) throws Exception {
System.out.println("consumer:" + Thread.currentThread().getName() + " Event: value=" + event.getValue() );
} }

4、ProducerConsumerMain 
消费者-生产者启动类,其依靠构造Disruptor对象,调用start()方法完成启动线程。

package com.ljq.disruptor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.WorkerPool;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.ProducerType; /**
* Disruptor多个消费者不重复处理生产者发送过来的消息
*
* @author Administrator
*
*/
public class ProducerConsumerMain {
public static void main(String[] args) throws InterruptedException {
Long time = System.currentTimeMillis(); // 指定 ring buffer字节大小,必需为2的N次方(能将求模运算转为位运算提高效率 ),否则影响性能
int bufferSize = 1024 * 1024;;
//固定线程数
int nThreads = 10; ExecutorService executor = Executors.newFixedThreadPool(nThreads); EventFactory<LongEvent> factory = new EventFactory<LongEvent>() {
@Override
public LongEvent newInstance() {
return new LongEvent();
}
}; // 创建ringBuffer
RingBuffer<LongEvent> ringBuffer = RingBuffer.create(ProducerType.MULTI, factory, bufferSize, new YieldingWaitStrategy());
SequenceBarrier barriers = ringBuffer.newBarrier();
// 创建10个消费者来处理同一个生产者发送过来的消息(这10个消费者不重复消费消息)
LongEventConsumer[] consumers = new LongEventConsumer[50];
for (int i = 0; i < consumers.length; i++) {
consumers[i] = new LongEventConsumer();
}
WorkerPool<LongEvent> workerPool = new WorkerPool<LongEvent>(ringBuffer, barriers,
new EventExceptionHandler(), consumers);
ringBuffer.addGatingSequences(workerPool.getWorkerSequences());
workerPool.start(executor); LongEventProducer producer = new LongEventProducer(ringBuffer);
for (int i = 0; i < 20000; i++) {
producer.produceData(i);
} Thread.sleep(1000); //等上1秒,等消费都处理完成
workerPool.halt(); //通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
executor.shutdown();
System.out.println("总共耗时(单位毫秒) :" + (System.currentTimeMillis() - time));
}
}

5、EventExceptionHandler

package com.ljq.disruptor;

import com.lmax.disruptor.ExceptionHandler;

public class EventExceptionHandler implements ExceptionHandler {

    @Override
public void handleEventException(Throwable ex, long sequence, Object event) {
System.out.println("handleEventException:" + ex);
} @Override
public void handleOnShutdownException(Throwable ex) {
System.out.println("handleEventException:" + ex);
} @Override
public void handleOnStartException(Throwable ex) {
System.out.println("handleOnStartException:" + ex);
} }

Disruptor多个消费者不重复处理生产者发送过来的消息的更多相关文章

  1. kafka 消费组功能验证以及消费者数据重复数据丢失问题说明 3

    原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 背景 上一篇文章记录了kafka的副本机制和容错功能的说明,本篇则主要在上一篇文章的基础上 ...

  2. rabbitmq消息队列,消息发送失败,消息持久化,消费者处理失败相关

    转:https://blog.csdn.net/u014373554/article/details/92686063 项目是使用springboot项目开发的,前是代码实现,后面有分析发送消息失败. ...

  3. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  4. 深入研究RocketMQ生产者发送消息的底层原理

    前言 hello,小伙伴们,王子又来和大家研究RocketMQ的原理了,之前的文章RocketMQ生产部署架构如何设计中,我们已经简单的聊过了生产者是如何发送消息给Broker的. 我们简单回顾一下这 ...

  5. java生产者/消费者模式实现——一生产者一消费者(操作值)

    胶多不粘话多不甜,直接上代码: 生产者类: /** * Created by 51304 on 2016/2/28. */ public class P { private String lock; ...

  6. 设有三个进程A、B、C,其中A与B构成一对生产者与消费者(A为生产者,B为消费者),共享一个由n个缓冲块组成的缓冲池;B与C也构成一对生产者与消费者(此时B为生产者,C为消费者)共享另一个由m个缓冲块组成的缓冲池。用P、V操作描述它们之间的同步关系。

    生产者消费者问题 设信号量mutex1, mutex2, full1, full2, empty1, empty2分别表示1和2号缓冲区的访问互斥, 是否满, 是否空 semaphore mutex1 ...

  7. kafka 生产者发送消息

    KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...

  8. RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个

    问题现象 RocketMQ3.2.2版本,测试时尝试发送消息时自动创建Topic,设置了队列数量为8: producer.setDefaultTopicQueueNums(8); 同时设置broker ...

  9. [SoapUI] 设置最大等待时间,不断重复的去发送一个request,每次从response中获取一个status,直到这个status从一种状态变成另外一种状态

    import com.eviware.soapui.support.GroovyUtils def groovyUtils = new GroovyUtils( context ) def holde ...

随机推荐

  1. 2018-01-13 view绘制流程-activity启动流程-window-decorView-ViewRootImpl关系

    1.activity启动流程: https://www.jianshu.com/p/927ca995bca6 http://blog.csdn.net/qian520ao/article/detail ...

  2. (转)ASP.NET MVC 第五个预览版和表单提交场景

    转自:http://ourlife.blog.51cto.com/708821/296171 上个星期四,ASP.NET MVC开发团队发布了ASP.NET MVC框架的“第五个预览版”.你可以在这里 ...

  3. web-day11

    第11章WEB11-Cookie&Session篇 今日任务 显示用户的上次访问时间 登录系统以后显示商品浏览记录 购买商品将商品添加到购物车 系统登录的验证码的校验 教学导航 教学目标 了解 ...

  4. Codeforces Round #265 (Div. 2) C. No to Palindromes! 构造不含回文子串的串

    http://codeforces.com/contest/465/problem/C 给定n和m,以及一个字符串s,s不存在长度大于2的回文子串,现在要求输出一个字典比s大的字符串,且串中字母在一定 ...

  5. StringBuffer 去掉最后一个字符

    StringBuffer stringBuffer=new StringBuffer (); stringBuffer.append("aaa,"); stringBuffer.d ...

  6. GeneralizedLinearAlgorithm in Spark MLLib

    GeneralizedLinearAlgorithm SparkMllib涉及到的算法 Classification Linear Support Vector Machines (SVMs) Log ...

  7. python threading模块2

    Thread 是threading模块中最重要的类之一,可以使用它来创建线程.有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法:另一种是创建一个threading.Thread对 ...

  8. Windows核心编程:第5章 作业

    Github https://github.com/gongluck/Windows-Core-Program.git //第5章 作业.cpp: 定义应用程序的入口点. // #include &q ...

  9. 使用Samba实现文件共享

    1987年,微软公司和英特尔公司,共同制定了SMB(Server Messages Block 服务消息块)协议,指在解决局域网内的文件或打印机等资源的共享问题,这也使得在多个主机之间共享文件变得越来 ...

  10. Android必学之AsyncTask

    AsyncTask,即异步任务,是Android给我们提供的一个处理异步任务的类.通过此类,可以实现UI线程和后台线程进行通讯,后台线程执行异步任务,并把结果返回给UI线程. .为什么需要使用异步任务 ...