并发框架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 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 ...
随机推荐
- 玩转ASP.NET Core中的日志组件
简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...
- 剖析HBase负载均衡和性能指标
1.概述 在分布式系统中,负载均衡是一个非常重要的功能,在HBase中通过Region的数量来实现负载均衡,HBase中可以通过hbase.master.loadbalancer.class来实现自定 ...
- 老代码多=过度耦合=if else?阿里巴巴工程师这样捋直老代码
简介 在业务开发的过程中,往往存在平台代码和业务代码耦合严重难以分离.业务和业务之间代码交织缺少拆解的现象.平台和业务代码交织导致不易修改,不同业务的代码交织增加了不同负责团队之间的协同成本.因此不论 ...
- [十四]基础类型之StringBuffer 与 StringBuilder对比
StringBuilder 和 StringBuffer是高度类似的两个类 StringBuilder是StringBuffer的版本改写,下面从几个方面简单的对比下他们的区别 类继承关系 上文中,我 ...
- 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)
一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...
- Oracle最新的Sql笔试题及答案
部门表(SM_DEPT) 字段名称 数据类型 是否主键 注释 DEPT_ID NUMBER Y 部门ID PARENT_DEPARTMENT_ID NUMBER N 上级部门 DEPARTMENT_N ...
- 解读经典《C#高级编程》第七版 Page94-100.继承.Chapter4
前言 今天,我们开始进入第四章的解读.本章讲的是继承.要做稍微复杂一些的开发,便不可避免的会使用到继承.本篇文章我们主要解读"实现继承". 另外,从本文开始,我开始使用Markdo ...
- (摘)linux下yum安装redis以及使用
1.yum install redis --查看是否有redis yum 源 2.yum install epel-release --下载fedora的epel仓库 3.yum ...
- Java集合类源码解析:AbstractList
今天学习Java集合类中的一个抽象类,AbstractList. 初识AbstractList AbstractList 是一个抽象类,实现了List<E>接口,是隶属于Java集合框架中 ...
- hbuilder vs2013api Access-Control-Allow-Origin
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" valu ...