入口:

  1. import java.nio.ByteBuffer;
  2. import java.util.UUID;
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.Executors;
  5.  
  6. import com.lmax.disruptor.EventFactory;
  7. import com.lmax.disruptor.ExceptionHandler;
  8. import com.lmax.disruptor.RingBuffer;
  9. import com.lmax.disruptor.SequenceBarrier;
  10. import com.lmax.disruptor.WorkHandler;
  11. import com.lmax.disruptor.WorkerPool;
  12. import com.lmax.disruptor.YieldingWaitStrategy;
  13. import com.lmax.disruptor.dsl.ProducerType;
  14.  
  15. public class Main {
  16.  
  17. public static void main(String[] args) throws Exception {
  18.  
  19. //创建ringBuffer
  20. RingBuffer<Order> ringBuffer =
  21. RingBuffer.create(ProducerType.MULTI,
  22. new EventFactory<Order>() {
  23. @Override
  24. public Order newInstance() {
  25. return new Order();
  26. }
  27. },
  28. 1024 * 1024,
  29. new YieldingWaitStrategy());
  30.  
  31. SequenceBarrier barriers = ringBuffer.newBarrier();
  32.  
  33. Consumer[] consumers = new Consumer[3];
  34. for(int i = 0; i < consumers.length; i++){
  35. consumers[i] = new Consumer("c" + i);
  36. }
  37.  
  38. WorkerPool<Order> workerPool =
  39. new WorkerPool<Order>(ringBuffer,
  40. barriers,
  41. new IntEventExceptionHandler(),
  42. consumers);
  43.  
  44. ringBuffer.addGatingSequences(workerPool.getWorkerSequences());
  45. workerPool.start(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));
  46.  
  47. final CountDownLatch latch = new CountDownLatch(1);
  48. for (int i = 0; i < 100; i++) {
  49. final Producer p = new Producer(ringBuffer);
  50. new Thread(new Runnable() {
  51. @Override
  52. public void run() {
  53. try {
  54. latch.await();
  55. } catch (InterruptedException e) {
  56. e.printStackTrace();
  57. }
  58. for(int j = 0; j < 100; j ++){
  59. p.onData(UUID.randomUUID().toString());
  60. }
  61. }
  62. }).start();
  63. }
  64. Thread.sleep(2000);
  65. System.out.println("---------------开始生产-----------------");
  66. latch.countDown();
  67. Thread.sleep(5000);
  68. System.out.println("总数:" + consumers[0].getCount() );
  69. }
  70.  
  71. static class IntEventExceptionHandler implements ExceptionHandler {
  72. public void handleEventException(Throwable ex, long sequence, Object event) {}
  73. public void handleOnStartException(Throwable ex) {}
  74. public void handleOnShutdownException(Throwable ex) {}
  75. }
  76. }

生产者

  1. import com.lmax.disruptor.RingBuffer;
  2. public class Producer {
  3.  
  4. private final RingBuffer<Order> ringBuffer;
  5.  
  6. public Producer(RingBuffer<Order> ringBuffer){
  7. this.ringBuffer = ringBuffer;
  8. }
  9.  
  10. /**
  11. * onData用来发布事件,每调用一次就发布一次事件
  12. * 它的参数会用过事件传递给消费者
  13. */
  14. public void onData(String data){
  15. //可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽
  16. long sequence = ringBuffer.next();
  17. try {
  18. //用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象)
  19. Order order = ringBuffer.get(sequence);
  20. //获取要通过事件传递的业务数据
  21. order.setId(data);
  22. } finally {
  23. //发布事件
  24. //注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的 sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。
  25. ringBuffer.publish(sequence);
  26. }
  27. }
  28.  
  29. }

消费者:

  1. import java.util.concurrent.atomic.AtomicInteger;
  2.  
  3. import com.lmax.disruptor.WorkHandler;
  4.  
  5. public class Consumer implements WorkHandler<Order>{
  6.  
  7. private String consumerId;
  8.  
  9. private static AtomicInteger count = new AtomicInteger(0);
  10.  
  11. public Consumer(String consumerId){
  12. this.consumerId = consumerId;
  13. }
  14.  
  15. @Override
  16. public void onEvent(Order order) throws Exception {
  17. System.out.println("当前消费者: " + this.consumerId + ",消费信息:" + order.getId());
  18. count.incrementAndGet();
  19. }
  20.  
  21. public int getCount(){
  22. return count.get();
  23. }
  24.  
  25. }

数据对象

  1. public class Order {
  2.  
  3. private String id;//ID
  4. private String name;
  5. private double price;//金额
  6.  
  7. public String getId() {
  8. return id;
  9. }
  10. public void setId(String id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public double getPrice() {
  20. return price;
  21. }
  22. public void setPrice(double price) {
  23. this.price = price;
  24. }
  25.  
  26. }

架构师养成记--17.disrunptor 多生产者多消费者的更多相关文章

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

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

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

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

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

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

  4. 架构师养成记--33.Redis哨兵、redis简单事务

    Redis哨兵 有了主从复制,如果我想想对主从服务器进行监控,在redis2.6后提供了哨兵机制,2.6有哨兵1.0版本,并不稳定.2.8以后的哨兵功能才稳定起来. 顾名思义,哨兵就是监控Redis系 ...

  5. 架构师养成记--16.disruptor并发框架中RingBuffer的使用

    很多时候我们只需要消息中间件这样的功能,那么直需要RinBuffer就可以了. 入口: import java.util.concurrent.Callable; import java.util.c ...

  6. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

  7. 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch

    java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...

  8. 架构师养成记--11.Executor概述

    常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...

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

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

随机推荐

  1. 11. Container With Most Water 装水最多的容器

    [抄题]: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ...

  2. Jenkins使用FTP进行一键部署及回滚2(Windows)(项目实践)

     转载:http://www.cnblogs.com/EasonJim/p/6295372.html Jenkins使用FTP进行一键部署及回滚2(Windows)(项目实践) 前提: 这一篇是继上一 ...

  3. Golang之排序算法

    冒泡排序 package main //冒泡排序 import "fmt" func bsort(a []int) { ; i < len(a); i++ { ; j < ...

  4. (OK) 国内常用NTP服务器地址及IP

    https://www.douban.com/note/171309770/ ntpdate s2c.time.edu.cn      北京邮电大学 ntpdate s2m.time.edu.cn   ...

  5. css控制两个表格的边线重合

    控制两个表格的边线重合 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  6. 前端福利之jQuery文字轮播特效(转)

    闲谈:离开学校那座象牙塔已经也有大半年的事件了,生活中不再充满了茫然只有忙碌.连续加班加点大半个月,做的活动项目终于算是告一段落了,而今天也将是考验其真正价值的时候,现在将这次开发中遇到的问题做一下总 ...

  7. context:propertyPlaceholder

    Activates replacement of ${...} placeholders by registering a PropertySourcesPlaceholderConfigurer w ...

  8. 加载 bean*.xml

    入口 ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean*.xml"); /** ...

  9. Git config 配置文件

    一.Git已经在你的系统中了,你会做一些事情来客户化你的Git环境.你只需要做这些设置一次:即使你升级了,他们也会绑定到你的环境中.你也可以在任何时刻通过运行命令来重新更改这些设置. Git有一个工具 ...

  10. 深入浅出 MappedByteBuffer

    前言 java io操作中通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java nio中引入了一种基于MappedByteBuffer操 ...