Disrunptor多生产者多消费者模型讲解
多生产者多消费者模拟需求:
1、创建100个订单生产者,每个生产者生产100条订单,总共会生产10000条订单,由3个消费者进行订单消费处理。
2、100个订单生产者全部创建完毕,再一起生产消费订单数据
1、定义事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package com.ljq.multi; public class Order { private String id; // ID private String name; private double price; // 金额 public String getId() { return id; } public void setId(String id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public double getPrice() { return price; } public void setPrice( double price) { this .price = price; } } |
2、生产者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.ljq.multi; import com.lmax.disruptor.RingBuffer; /** * 生产者 * * @author Administrator * */ public class Producer { private final RingBuffer<Order> ringBuffer; public Producer(RingBuffer<Order> ringBuffer) { this .ringBuffer = ringBuffer; } /** * onData用来发布事件,每调用一次就发布一次事件 它的参数会用过事件传递给消费者 */ public void onData(String data) { // 可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽 long sequence = ringBuffer.next(); try { // 用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象) Order order = ringBuffer.get(sequence); // 获取要通过事件传递的业务数据 order.setId(data); } finally { // 发布事件 // 注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的 // sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。 ringBuffer.publish(sequence); } } } |
3、消费者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.ljq.multi; import java.util.concurrent.atomic.AtomicInteger; import com.lmax.disruptor.WorkHandler; public class Consumer implements WorkHandler<Order>{ private String consumerId; private static AtomicInteger count = new AtomicInteger( 0 ); public Consumer(String consumerId){ this .consumerId = consumerId; } @Override public void onEvent(Order order) throws Exception { count.incrementAndGet(); System.out.println( "当前消费者: " + this .consumerId + ",消费信息:" + order.getId() + ",count:" + getCount()); } public int getCount(){ return count.get(); } } |
4、生产者消费者启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | package com.ljq.multi; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import com.lmax.disruptor.EventFactory; import com.lmax.disruptor.ExceptionHandler; import com.lmax.disruptor.RingBuffer; import com.lmax.disruptor.SequenceBarrier; import com.lmax.disruptor.WorkerPool; import com.lmax.disruptor.YieldingWaitStrategy; import com.lmax.disruptor.dsl.ProducerType; /** * disrunptor 多生产者多消费者 * * @author Administrator * */ public class Main { public static void main(String[] args) throws Exception { //创建ringBuffer RingBuffer<Order> ringBuffer = RingBuffer.create(ProducerType.MULTI, new EventFactory<Order>() { @Override public Order newInstance() { return new Order(); } }, 1024 * 1024 , new YieldingWaitStrategy()); SequenceBarrier barriers = ringBuffer.newBarrier(); //创建3个消费者消费订单数据 Consumer[] consumers = new Consumer[ 3 ]; for ( int i = 0 ; i < consumers.length; i++){ consumers[i] = new Consumer( "c" + i); } WorkerPool<Order> workerPool = new WorkerPool<Order>(ringBuffer, barriers, new IntEventExceptionHandler(), consumers); ringBuffer.addGatingSequences(workerPool.getWorkerSequences()); workerPool.start(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())); final AtomicInteger count = new AtomicInteger( 0 ); final CountDownLatch latch = new CountDownLatch( 1 ); //100个生产者 for ( int i = 0 ; i < 100 ; i++) { final Producer p = new Producer(ringBuffer); new Thread( new Runnable() { @Override public void run() { try { System.out.println(count.incrementAndGet()); latch.await(); //等待,直到100个生产者创建完成,再一起生产消费订单数据 } catch (InterruptedException e) { e.printStackTrace(); } //每个生产者生产100条订单 for ( int j = 0 ; j < 100 ; j ++){ p.onData(UUID.randomUUID().toString()); } } }).start(); } System.out.println( "---------------开始生产-----------------" ); latch.countDown(); //生产者全部创建完毕,开始生产订单 } static class IntEventExceptionHandler implements ExceptionHandler { public void handleEventException(Throwable ex, long sequence, Object event) {} public void handleOnStartException(Throwable ex) {} public void handleOnShutdownException(Throwable ex) {} } } |
分类:
并发编程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
2011-09-03 html5教程
2011-09-03 二十四、按后退键退出Android程序