Disruptor是什么,怎么使用,网上有很多教材,但有些过于复杂,剖析了Disruptor的方方面面,实际上对应普通的开发人员,使用这个工具,只需要指导知道大概原理和使用方法,并不需要知道非常深入的原理。

有些文章则是写了错误的实例,或者只是摘取了项目的一段代码,实际上,要把这些代码转化成项目的实际代码,却发现困难重重。

这个文章主要是针对想提高性能,在项目组使用Disruptor的开发人员写的,会简单讲解它的一些原理,尽量把代码简单,但又包括项目使用中必须的方方面面。

——Disruptor的使用场景

一个字,就是快,经过测试,Disruptor的速度比LinkedBlockingQueue提高了七倍。所以,当你在使用LinkedBlockingQueue出现性能瓶颈的时候,你就可以考虑采用Disruptor的代替。

当然,Disruptor性能高并不是必然的,所以,是否使用还得经过测试。

Disruptor的最常用的场景就是“生产者-消费者”场景,对场景的就是“一个生产者、多个消费者”的场景,并且要求顺序处理。

举个例子,我们从MySQL的BigLog文件中顺序读取数据,然后写入到ElasticSearch(搜索引擎)中。在这种场景下,BigLog要求一个文件一个生产者,那个是一个生产者。而写入到ElasticSearch,则严格要求顺序,否则会出现问题,所以通常意义上的多消费者线程无法解决该问题,如果通过加锁,则性能大打折扣。

——一个生产者,多消费者例子

在贴出代码之前,这里简单讲一下代码的结构和说明。简单的图示如下,先有Producer来作为生产者,发送事件。由EventHandler作为消费者,处理事件。

这个实例代码很简单,就是由生产者发送一个字符串到Disruptor,然后消费者处理该事件,并把字符串打印处理。

下面是各个Java类的说明:

HelloEventProducer:生产者,负责传递一个字符串,并发布事件

HelloEventHandler:消费者,负责消费事件,并打印字符串

HelloEventFactory:事件工厂类,负责初始化一个事件

HelloEvent:表示一个事件

DisruptorMain:运行的主程序,负责将整个逻辑连接起来

  1. package com.disruptor;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import com.lmax.disruptor.EventFactory;
  5. import com.lmax.disruptor.EventHandler;
  6. import com.lmax.disruptor.RingBuffer;
  7. import com.lmax.disruptor.WaitStrategy;
  8. import com.lmax.disruptor.YieldingWaitStrategy;
  9. import com.lmax.disruptor.dsl.Disruptor;
  10. import com.lmax.disruptor.dsl.ProducerType;
  11. public class DisruptorMain {
  12. public static void main(String[] args){
  13. ExecutorService executor = Executors.newFixedThreadPool(3);
  14. // WaitStrategy blockingWaitStrategy = new BlockingWaitStrategy();
  15. // WaitStrategy sleepingWaitStrategy = new SleepingWaitStrategy();
  16. WaitStrategy yieldingWaitStrategy = new YieldingWaitStrategy();
  17. EventFactory<HelloEvent> eventFactory = new HelloEventFactory();
  18. int ringBufferSize = 1024 * 1024;
  19. Disruptor<HelloEvent> disruptor = new Disruptor<HelloEvent>(eventFactory,
  20. ringBufferSize, executor, ProducerType.SINGLE
  21. , yieldingWaitStrategy);
  22. EventHandler<HelloEvent> eventHandler = new HelloEventHandler();
  23. disruptor.handleEventsWith(eventHandler);
  24. disruptor.start();
  25. RingBuffer<HelloEvent> ringBuffer = disruptor.getRingBuffer();
  26. HelloEventProducer producer = new HelloEventProducer(ringBuffer);
  27. for(long l = 0; l<100; l++){
  28. producer.onData("黄育源:Hello World!!!:" + l);
  29. }
  30. }
  31. }
  1. package com.disruptor;
  2. public class HelloEvent {
  3. private String value;
  4. public String getValue() {
  5. return value;
  6. }
  7. public void setValue(String value) {
  8. this.value = value;
  9. }
  10. }
  1. package com.disruptor;
  2. import com.lmax.disruptor.EventFactory;
  3. public class HelloEventFactory implements EventFactory<HelloEvent>{
  4. @Override
  5. public HelloEvent newInstance() {
  6. return new HelloEvent();
  7. }
  8. }
  1. package com.disruptor;
  2. import com.lmax.disruptor.EventHandler;
  3. public class HelloEventHandler implements EventHandler<HelloEvent>{
  4. @Override
  5. public void onEvent(HelloEvent event, long sequence, boolean endOfBatch) throws Exception {
  6. System.out.println(event.getValue());
  7. }
  8. }
  1. package com.disruptor;
  2. import com.lmax.disruptor.RingBuffer;
  3. public class HelloEventProducer implements Runnable{
  4. private final RingBuffer<HelloEvent> ringBuffer;
  5. public HelloEventProducer(RingBuffer<HelloEvent> ringBuffer){
  6. this.ringBuffer = ringBuffer;
  7. }
  8. /**
  9. * onData用来发布事件,每调用一次就发布一次事件
  10. * 它的参数会用过事件传递给消费者
  11. */
  12. public void onData(String str){
  13. long sequence = ringBuffer.next();
  14. System.out.println(sequence);
  15. try{
  16. HelloEvent event = ringBuffer.get(sequence);
  17. event.setValue(str);
  18. }finally{
  19. ringBuffer.publish(sequence);
  20. }
  21. }
  22. @Override
  23. public void run() {
  24. for(long l = 0; l<100; l++){
  25. this.onData("黄育源:Hello World!!!:" + l);
  26. }
  27. }
  28. }

转载于:https://www.cnblogs.com/kekexuanxaun/p/9480302.html

Disruptor高性能缓存队列入门指导相关推荐

  1. JAVA高性能内存队列-disruptor

    JAVA内置队列 高性能内存队列-disruptor disruptor为啥这么快 无锁设计 内部采用CAS方式获取下一个任务序列号,没有锁竞争,不需要线程上下文切换 伪共享问题解决 当多线程修改互相 ...

  2. 高性能内存队列Disruptor

    一.简介 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级). 基于Disruptor开发的系统单 ...

  3. 如何快速实现分布式定时器丨红黑树|跳表|堆|时间轮|缓存|锁|事务|架构|高性能|消息队列丨C/C++Linux服务器开发丨C++后端开发

    如何快速实现分布式定时器 视频讲解如下,点击观看: 如何快速实现分布式定时器丨红黑树|跳表|堆|时间轮|缓存|锁|事务|架构|高性能|消息队列丨C/C++Linux服务器开发丨C++后端开发丨中间件 ...

  4. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 1 package com.ws.commons.cache; 2 3 import java.util.functio ...

  5. Redis高性能缓存数据库

    Redis高性能缓存数据库 Redis 基础入 Redis 介绍 特性 使用场景 正确安装与启动 重要的指令使用 全局命令 单线程架构 字符串 - String 内部编码 应用场景 哈希 - Hash ...

  6. osg自学笔记1——《OpenSceneGraph 快速入门指导》

    这里写自定义目录标题 <OpenSceneGraph Quick Start Guide>学习笔记 1. 1.3 运行 osgviewer 2.1.5 场景图形初步 3. 1.6 Open ...

  7. Redis一通百通~P8架构师带你玩转Redis高性能缓存设计实战

    前言 高并发十分考验架构师功底,它也是分布式架构设计中必须考虑的因素之一.要知道,光靠服务器堆是没有出路的. 想看看大牛是怎么面对高并发的?想知道BATJ大厂是怎么设计高可用架构的?这里有可参考的实践 ...

  8. 高性能缓存服务器 Nuster

    Nuster 是一个基于 HAProxy 的高性能缓存服务器.Nuster 完全兼容 HAProxy,并且利用 HAProxy 的 ACL 功能来提供非常细致的缓存规则,比如 请求地址为某某时缓存 请 ...

  9. java高性能阻塞队列,Linux c/c   后台开发组建之:高性能阻塞队列

    Linux c/c   后台开发组建之:高性能阻塞队列 (2015-12-01 06:01:47) 标签: Linux c/c 杂谈 分类: c/c 阻塞队列是后台开发中多线程异步架构的基本数据结构, ...

最新文章

  1. git常用命令的使用
  2. Jupyter notebook入门教程(上)
  3. java main是多线程的吗_Java多线程之线程及其常用方法
  4. php中改变函数路由,php – 如何修改codeigniter中的路由
  5. 最早的齿轮计算机,世界最古老“计算机”出土后110年,科学家终于解开它的秘密...
  6. 浅析Kerberos原理,及其应用和管理
  7. bootstrapr表格父子框_JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)...
  8. 2013阿里技术嘉年华:阿里数据同步前世今生
  9. java 怎么获取object的数据_自学java,想将来从事大数据工作,现实吗?怎么学?...
  10. 分离圆环图显示百分比_excel这个百分比图,你不一定会制作
  11. MySQL主从同步的概述_MySQL主从同步原理介绍
  12. VMware系统运维(十一)部署虚拟化桌面 Horizon View 5.2 HTML ACCESS安装
  13. ubuntu上编译fortran_Ubuntu下安装Intel Fortran编译器(ifort)
  14. python 返回列表长度_Python通过len函数返回对象长度
  15. html缩小照片尺寸像素不变,怎么修改照片像素,但又不改变照片大小呢?——解决照片因大小无法上传的方案...
  16. 神舟战神换cpu教程_神舟战神能换什么cpu 神舟战神Z7可以换CPU吗
  17. 118、交换机配置规范
  18. 导出excel file-saver XLSX
  19. html5青蛙过河,[推荐]===PS4上的本地多人游戏推荐心得===家庭聚会,欢乐时光 (持续更新)...
  20. ubuntu 18.04 使用intel核显画面撕裂解决办法

热门文章

  1. 用VisualBrush定制复杂的按钮样式
  2. 大快HanLP自然语言处理技术介绍
  3. 勒索软件好多都使用恶意LNK链接文件欺骗用户 来看趋势科技分析新型LNK-PowerShell攻击...
  4. OpenResty(nginx)操作mysql的初步应用
  5. 第六课-Android四大组件之Activity
  6. 密钥怎么存储在数据库中
  7. [原创]利用WM_COPYDATA实现进程间通信
  8. .Net/C# 实现真正的只读的 Hashtable 类型的属性 (ReadOnly Hashtable Property)
  9. 批处理查找html,批处理(bat)实现全盘搜索指定文件获取其完整路径方法大全,bat大全分享...
  10. 485通讯的校验和_RS485通讯如何实现三菱PLC对三菱变频器的控制?