很多时候我们只需要消息中间件这样的功能,那么直需要RinBuffer就可以了。

入口:

  1. import java.util.concurrent.Callable;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.Future;
  5.  
  6. import com.lmax.disruptor.BatchEventProcessor;
  7. import com.lmax.disruptor.EventFactory;
  8. import com.lmax.disruptor.RingBuffer;
  9. import com.lmax.disruptor.SequenceBarrier;
  10. import com.lmax.disruptor.YieldingWaitStrategy;
  11.  
  12. public class Main1 {
  13.  
  14. public static void main(String[] args) throws Exception {
  15. int BUFFER_SIZE=1024;
  16. int THREAD_NUMBERS=4;
  17. /*
  18. * createSingleProducer创建一个单生产者的RingBuffer,
  19. * 第一个参数叫EventFactory,从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块。
  20. * 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率
  21. * 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略
  22. */
  23. final RingBuffer<Trade> ringBuffer = RingBuffer.createSingleProducer(new EventFactory<Trade>() {
  24. @Override
  25. public Trade newInstance() {
  26. return new Trade();
  27. }
  28. }, BUFFER_SIZE, new YieldingWaitStrategy());
  29.  
  30. //创建线程池
  31. ExecutorService executors = Executors.newFixedThreadPool(THREAD_NUMBERS);
  32.  
  33. //创建SequenceBarrier
  34. SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
  35.  
  36. /****************** @beg 消费者消费数据 2017-1-11******************/
  37. //创建消息处理器
  38. BatchEventProcessor<Trade> transProcessor = new BatchEventProcessor<Trade>(
  39. ringBuffer, sequenceBarrier, new TradeHandler());
  40.  
  41. //这一步的目的就是把消费者的位置信息引用注入到生产者 如果只有一个消费者的情况可以省略
  42. ringBuffer.addGatingSequences(transProcessor.getSequence());
  43.  
  44. //把消息处理器提交到线程池
  45. executors.submit(transProcessor);
  46. /****************** @end 消费者消费数据 2017-1-11******************/
  47.  
  48. //如果存在多个消费者 那重复执行上面3行代码 把TradeHandler换成其它消费者类
  49.  
  50. /****************** @beg 生产者生产数据 2017-1-11******************/
  51.  
  52. Future<?> future= executors.submit(new Callable<Void>() {
  53. @Override
  54. public Void call() throws Exception {
  55. long seq;
  56. for(int i=0;i<10;i++){
  57. seq = ringBuffer.next();//占个坑 --ringBuffer一个可用区块
  58. ringBuffer.get(seq).setPrice(Math.random()*9999);//给这个区块放入 数据
  59. ringBuffer.publish(seq);//发布这个区块的数据使handler(consumer)可见
  60. }
  61. return null;
  62. }
  63. });
  64.  
  65. /****************** @end 生产者生产数据 2017-1-11******************/
  66.  
  67. future.get();//等待生产者结束
  68. Thread.sleep(1000);//等上1秒,等消费都处理完成
  69. transProcessor.halt();//通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
  70. executors.shutdown();//终止线程
  71. }
  72. }

消费者:

  1. import java.util.UUID;
  2.  
  3. import com.lmax.disruptor.EventHandler;
  4. import com.lmax.disruptor.WorkHandler;
  5.  
  6. public class TradeHandler implements EventHandler<Trade>, WorkHandler<Trade> {
  7.  
  8. @Override
  9. public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
  10. this.onEvent(event);
  11. }
  12.  
  13. @Override
  14. public void onEvent(Trade event) throws Exception {
  15. //这里做具体的消费逻辑
  16. event.setId(UUID.randomUUID().toString());//简单生成下ID
  17. System.out.println(event.getId());
  18. }
  19. }

数据对象:

  1. import java.util.concurrent.atomic.AtomicInteger;
  2.  
  3. public class Trade {
  4.  
  5. private String id;//ID
  6. private String name;
  7. private double price;//金额
  8. private AtomicInteger count = new AtomicInteger(0);
  9.  
  10. public String getId() {
  11. return id;
  12. }
  13. public void setId(String id) {
  14. this.id = id;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. public double getPrice() {
  23. return price;
  24. }
  25. public void setPrice(double price) {
  26. this.price = price;
  27. }
  28. public AtomicInteger getCount() {
  29. return count;
  30. }
  31. public void setCount(AtomicInteger count) {
  32. this.count = count;
  33. }
  34.  
  35. }

架构师养成记--16.disruptor并发框架中RingBuffer的使用的更多相关文章

  1. 架构师养成记--15.Disruptor并发框架

    一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...

  2. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  3. 架构师养成记--10.master-worker模式

    master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...

  4. 架构师养成记--8.Queue

    一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...

  5. 架构师养成记--32.Redis高级(安全 主从复制)

    Redis高级命令及特性 keys * 返回满足的所有键值(*表示模糊匹配) exists 是否存在指定的key(返回1表示存在,0表示不存在) expire 设置某个key的过期时间,使用ttl查看 ...

  6. 架构师养成记--29.redis开篇

    主要有从下几点讲解 NOSQL(Redis) 简介.redis安装与部署 Redis基础事件类型详解 Redis高级命令 Redis与java的使用 Redis集群搭建 Redis集群与spring的 ...

  7. 架构师养成记--21.netty编码解码

    背景 作为网络传输框架,免不了哟啊传输对象,对象在传输之前就要序列化,这个序列化的过程就是编码过程.接收到编码后的数据就需要解码,还原传输的数据. 代码 工厂类 import io.netty.han ...

  8. 架构师养成记--19.netty

    一.Netty初步 为什么选择Netty? 和NIO比较,要实现一个通信要简单得很多,性能很好.分布式消息中间件.storm.Dubble都是使用Netty作为底层通信. Netty5.0要求jdk1 ...

  9. 架构师养成记--17.disrunptor 多生产者多消费者

    入口: import java.nio.ByteBuffer; import java.util.UUID; import java.util.concurrent.CountDownLatch; i ...

随机推荐

  1. [leetcode]134. Gas Station加油站

      There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. Y ...

  2. MySqlDBHelper

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syste ...

  3. DART: a fast and accurate RNA-seq mapper with a partitioning strategy DART:使用分区策略的快速准确的RNA-seq映射器

    DART: a fast and accurate RNA-seq mapper with a partitioning strategyDART:使用分区策略的快速准确的RNA-seq映射器 Abs ...

  4. 本周MySQL官方verified/open的bug列表(11月15日至11月21日)

    本周MySQL verified的bug列表(11月15日至11月21日) 1. Bug #70923    Replication failure on multi-statement INSERT ...

  5. 5 CrawlSpider操作

    CrawlSpider 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Reques ...

  6. break,continue以及pass的使用

    1.break是提前结束循环 for i in range(1,100): if i%2 == 0: print("wrong") break#直接结束循环,并且不打印下面的pri ...

  7. js 中的 2 与 "2"

    case1: "15" * 2 结果:30 case2: 2 * "15" 结果:30 case3: "2" * "15" ...

  8. WIP and COST Frequently Used Troubleshooting Scripts (Doc ID 105647.1)

    Applies to: Oracle Work in Process - Version 10.7.16.1 to 12.1 [Release 10.7 to 12.1] Information in ...

  9. Centos 下安装tomcat多实例

    基础环境及JDK就不多说了,下面的目录结构以如下为准: 根目录-apps根目录-apps--tomcat根目录-apps--ins1根目录-apps--ins2 =================== ...

  10. kubernetes yaml

    apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Deployment #指定创建资源的角色/类型 metadata: #资源的元数据/属性 ...