并发框架Disruptor场景应用
- public class MyInParkingDataEvent {
- private String carLicense; // 车牌号
- public String getCarLicense() {
- return carLicense;
- }
- public void setCarLicense(String carLicense) {
- this.carLicense = carLicense;
- }
- }
Handler类:一个负责存储汽车数据,一个负责发送kafka信息到其他系统中,最后一个负责给车主发短信通知
- import com.lmax.disruptor.EventHandler;
- import com.lmax.disruptor.WorkHandler;
- /**
- * Handler 第一个消费者,负责保存进场汽车的信息
- *
- */
- public class MyParkingDataInDbHandler implements EventHandler<MyInParkingDataEvent> , WorkHandler<MyInParkingDataEvent>{
- @Override
- public void onEvent(MyInParkingDataEvent myInParkingDataEvent) throws Exception {
- long threadId = Thread.currentThread().getId(); // 获取当前线程id
- String carLicense = myInParkingDataEvent.getCarLicense(); // 获取车牌号
- System.out.println(String.format("Thread Id %s 保存 %s 到数据库中 ....", threadId, carLicense));
- }
- @Override
- public void onEvent(MyInParkingDataEvent myInParkingDataEvent, long sequence, boolean endOfBatch)
- throws Exception {
- this.onEvent(myInParkingDataEvent);
- }
- }
- import com.lmax.disruptor.EventHandler;
- /**
- * 第二个消费者,负责发送通知告知工作人员(Kafka是一种高吞吐量的分布式发布订阅消息系统)
- */
- public class MyParkingDataToKafkaHandler implements EventHandler<MyInParkingDataEvent>{
- @Override
- public void onEvent(MyInParkingDataEvent myInParkingDataEvent, long sequence, boolean endOfBatch)
- throws Exception {
- long threadId = Thread.currentThread().getId(); // 获取当前线程id
- String carLicense = myInParkingDataEvent.getCarLicense(); // 获取车牌号
- System.out.println(String.format("Thread Id %s 发送 %s 进入停车场信息给 kafka系统...", threadId, carLicense));
- }
- }
- import com.lmax.disruptor.EventHandler;
- /**
- * 第三个消费者,sms短信服务,告知司机你已经进入停车场,计费开始。
- */
- public class MyParkingDataSmsHandler implements EventHandler<MyInParkingDataEvent>{
- @Override
- public void onEvent(MyInParkingDataEvent myInParkingDataEvent, long sequence, boolean endOfBatch)
- throws Exception {
- long threadId = Thread.currentThread().getId(); // 获取当前线程id
- String carLicense = myInParkingDataEvent.getCarLicense(); // 获取车牌号
- System.out.println(String.format("Thread Id %s 给 %s 的车主发送一条短信,并告知他计费开始了 ....", threadId, carLicense));
- }
- }
Producer类:负责上报停车数据
- import java.util.concurrent.CountDownLatch;
- import com.lmax.disruptor.EventTranslator;
- import com.lmax.disruptor.dsl.Disruptor;
- /**
- * 生产者,进入停车场的车辆
- */
- public class MyInParkingDataEventPublisher implements Runnable{
- private CountDownLatch countDownLatch; // 用于监听初始化操作,等初始化执行完毕后,通知主线程继续工作
- private Disruptor<MyInParkingDataEvent> disruptor;
- private static final Integer NUM = 1; // 1,10,100,1000
- public MyInParkingDataEventPublisher(CountDownLatch countDownLatch,
- Disruptor<MyInParkingDataEvent> disruptor) {
- this.countDownLatch = countDownLatch;
- this.disruptor = disruptor;
- }
- @Override
- public void run() {
- MyInParkingDataEventTranslator eventTranslator = new MyInParkingDataEventTranslator();
- try {
- for(int i = 0; i < NUM; i ++) {
- disruptor.publishEvent(eventTranslator);
- Thread.sleep(1000); // 假设一秒钟进一辆车
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- countDownLatch.countDown(); // 执行完毕后通知 await()方法
- System.out.println(NUM + "辆车已经全部进入进入停车场!");
- }
- }
- }
- class MyInParkingDataEventTranslator implements EventTranslator<MyInParkingDataEvent> {
- @Override
- public void translateTo(MyInParkingDataEvent myInParkingDataEvent, long sequence) {
- this.generateData(myInParkingDataEvent);
- }
- private MyInParkingDataEvent generateData(MyInParkingDataEvent myInParkingDataEvent) {
- myInParkingDataEvent.setCarLicense("车牌号: 鄂A-" + (int)(Math.random() * 100000)); // 随机生成一个车牌号
- System.out.println("Thread Id " + Thread.currentThread().getId() + " 写完一个event");
- return myInParkingDataEvent;
- }
- }
执行的Main方法:
- import com.lmax.disruptor.EventFactory;
- import com.lmax.disruptor.YieldingWaitStrategy;
- import com.lmax.disruptor.dsl.Disruptor;
- import com.lmax.disruptor.dsl.EventHandlerGroup;
- import com.lmax.disruptor.dsl.ProducerType;
- /**
- * 执行的Main方法 ,
- * 一个生产者(汽车进入停车场);
- * 三个消费者(一个记录汽车信息,一个发送消息给系统,一个发送消息告知司机)
- * 前两个消费者同步执行,都有结果了再执行第三个消费者
- */
- public class MyInParkingDataEventMain {
- public static void main(String[] args) {
- long beginTime=System.currentTimeMillis();
- int bufferSize = 2048; // 2的N次方
- try {
- // 创建线程池,负责处理Disruptor的四个消费者
- ExecutorService executor = Executors.newFixedThreadPool(4);
- // 初始化一个 Disruptor
- Disruptor<MyInParkingDataEvent> disruptor = new Disruptor<MyInParkingDataEvent>(new EventFactory<MyInParkingDataEvent>() {
- @Override
- public MyInParkingDataEvent newInstance() {
- return new MyInParkingDataEvent(); // Event 初始化工厂
- }
- }, bufferSize, executor, ProducerType.SINGLE, new YieldingWaitStrategy());
- // 使用disruptor创建消费者组 MyParkingDataInDbHandler 和 MyParkingDataToKafkaHandler
- EventHandlerGroup<MyInParkingDataEvent> handlerGroup = disruptor.handleEventsWith(
- new MyParkingDataInDbHandler(), new MyParkingDataToKafkaHandler());
- // 当上面两个消费者处理结束后在消耗 smsHandler
- MyParkingDataSmsHandler myParkingDataSmsHandler = new MyParkingDataSmsHandler();
- handlerGroup.then(myParkingDataSmsHandler);
- // 启动Disruptor
- disruptor.start();
- CountDownLatch countDownLatch = new CountDownLatch(1); // 一个生产者线程准备好了就可以通知主线程继续工作了
- // 生产者生成数据
- executor.submit(new MyInParkingDataEventPublisher(countDownLatch, disruptor));
- countDownLatch.await(); // 等待生产者结束
- disruptor.shutdown();
- executor.shutdown();
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("总耗时:"+(System.currentTimeMillis()-beginTime));
- }
- }
--------------------- 本文来自 ITDragon龙 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_19558705/article/details/77247912?utm_source=copy
并发框架Disruptor场景应用的更多相关文章
- 无锁并发框架Disruptor学习入门
刚刚听说disruptor,大概理一下,只为方便自己理解,文末是一些自己认为比较好的博文,如果有需要的同学可以参考. 本文目标:快速了解Disruptor是什么,主要概念,怎么用 1.Disrupto ...
- 并发框架Disruptor译文
Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平台上,其核心是一个业务逻辑 ...
- 并发框架Disruptor浅析
1.引言 Disruptor是一个开源的Java框架,它被设计用于在生产者—消费者(producer-consumer problem,简称PCP)问题上获得尽量高的吞吐量(TPS)和尽量低的延迟.D ...
- Java 并发框架Disruptor(七)
Disruptor VS BlockingQueue的压测对比: import java.util.concurrent.ArrayBlockingQueue; public class ArrayB ...
- Disruptor并发框架(一)简介&上手demo
框架简介 Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平台上,其核心是一 ...
- 并发编程之Disruptor并发框架
一.什么是Disruptor Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JV ...
- Disruptor 并发框架
什么是Disruptor Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平 ...
- Disruptor并发框架简介
Martin Fowler在自己网站上写一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金额交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平台上,其核心是一个业务逻辑处 ...
- 来,带你鸟瞰 Java 中4款常用的并发框架!
1. 为什么要写这篇文章 几年前 NoSQL 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 ...
随机推荐
- .NET Core 多项目工程生成EF迁移代码
错误表现 dotnet ef的官方文档针对的是单个项目的情况,即启动项目就是DbContext所在项目. 对于分层结构的解决方案如启动项目是WebApi项目,DbContext在基础设施项目,在Web ...
- 使用Genymotion遇到的坑_Genymotion无法启动_unable to start the virtual device
Genymotion 十分好用,以下是我使用Genymotion碰到的问题及解决办法.目前没有看到网上有完整的解决. 遇到如下图的问题: 这个问题很多人可能回去百度“the virtual devic ...
- Solr 06 - Solr中配置使用IK分词器 (配置schema.xml)
目录 1 配置中文分词器 1.1 准备IK中文分词器 1.2 配置schema.xml文件 1.3 重启Tomcat并测试 2 配置业务域 2.1 准备商品数据 2.2 配置商品业务域 2.3 配置s ...
- Spring 完美配置跨域请求
在SpringBoot2.0 上的跨域 用以下代码配置 即可完美解决你的前后端跨域请求问题 import org.springframework.context.annotation.Bean; im ...
- 如何把你的.net程序打包上传到nuget
写在前面 每个.net开发者都经常用nuget管理自己的程序包,install一个json组件啊,一个工具类什么的,这些都是别人写好的.如果我也写好了一个自己感觉很拿的出手的组件,想轻松的使用nuge ...
- google的GCM推送使用简介
pom <!-- https://mvnrepository.com/artifact/com.google.gcm/gcm-server --> <dependency> & ...
- ueditor上传图片尺寸过大导致显示难看的解决办法
昨天遇到这个问题,我也是折腾成了狗, 到处查,最后收集到三个办法,记录一下. 代码贴这里,方便复制 img { max-width: 100%; /*图片自适应宽度*/ } body { overfl ...
- NTP服务器搭建
NTP服务器搭建 :http://www.jbxue.com/LINUXjishu/22352.html 客户端配置: vim /etc/ntp.conf #server 0.centos.pool. ...
- Spring Boot 2.x (二):How Hello World & 热部署
本篇摘要 上一篇文章,我们构建了一个HelloWorld的程序,现在,我们来看一下这个程序,下面是我们这一节要分析的点. spring-boot-starter-boot @SpringBootApp ...
- DSAPI多功能组件编程应用-文件类
[DSAPI.DLL下载地址] 本节内容,是属于"无需过多说明"就能使用的功能.由于实在是太简单,我就简单地示例一下. DSAPI.文件类.获取可读性强的字节大小信息(&q ...