并发框架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 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 ...
随机推荐
- 设计模式总结篇系列:单例模式(SingleTon)
在Java设计模式中,单例模式相对来说算是比较简单的一种构建模式.适用的场景在于:对于定义的一个类,在整个应用程序执行期间只有唯一的一个实例对象.如Android中常见的Application对象. ...
- python基础5--输入输出、错误与异常
1.键盘输入输出 输入:input()和raw_input() 输出:str()和format raw_input([prompt]) 函数从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符): ...
- Linux常用命令详解(week1_day1_2)--技术流ken
本节内容 aliasunaliasunamesuhostnamehistorywhichwcwwhowhoamipingkillseqdudffreedate 命令详解 1. alias 设置.’查看 ...
- SpringBoot系列——Spring-Data-JPA
前言 jpa是ORM映射框架,更多详情,请戳:apring-data-jpa官网:http://spring.io/projects/spring-data-jpa,以及一篇优秀的博客:https:/ ...
- Linux中more和less命令用法
一.more命令 more功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 ...
- BaseServlet的编写
在BaseServlet之前,需要提及工厂factory去管理dao以及service,以及页面转发或重定向的管理 1.创建一个工厂类,以及一个资源文件,资源文件中以键值对的形式去存储key,以及对应 ...
- MySQL5.7开多实例指导
一.mysql多实例原理 在一台服务器上,mysql服务开启多个不同的端口,运行多个服务进程.他们通过不同的 socket来监听不同的端口互不干扰地运行. 二.开发环境 ubuntu16.04.5LT ...
- Vue中父组件传子组件
父组件代码: <template> <section :class="menuMode === 'vertical' ? 'vertical-sub-nav' : 'sub ...
- 从.Net到Java学习第十二篇——SpringBoot+JPA提供跨域接口
从.Net到Java学习系列目录 最近又撸了半个月的前端代码,做app离线存储,然后又花了一周去将过去的wcf项目转webapi,java又被落下了,总感觉我特么像斗地主中的癞子牌,变来变去..... ...
- 美团技术沙龙01 - 58到家服务的订单调度&数据分析技术
1. 2015.4.15 到家服务的订单调度&数据分析技术 58到家· 黄海斌 @xemoaya 2.agenda • 58到家介绍 • 订单管理系统介绍 • 数据分析技术的应用 3.2015 ...