当前位置: 首页 > news >正文

并发框架disruptor实现生产-消费者模式

 `Disruptor`是LMAX公司开源的高性能内存消息队列,单线程处理能力可达600w订单/秒。本文将使用该框架实现生产-消费者模式。

一、框架的maven依赖

   <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version></dependency>

二、消息事件

package com.monika.main.system.mq;import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventProcessor;import java.util.EventObject;/*** @author:whh* @date: 2024-12-04 20:27* <p></p>*/
public class MsgEvent  {private String data;public String getData() {return data;}public void setData(String data) {this.data = data;}
}

三、消息事件处理器

package com.monika.main.system.mq;import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;/*** @author:whh* @date: 2024-12-04 22:28* <p>*     *     * </p>*/
public class MsgEventHandler implements EventHandler<MsgEvent>, WorkHandler<MsgEvent> {private String name;public MsgEventHandler(String name) {this.name = name;}@Overridepublic void onEvent(MsgEvent event, long sequence, boolean endOfBatch) throws Exception {System.out.println(name+"-----start-----"+sequence);Thread.sleep(1000*10);System.out.println("ThreadName:  "+Thread.currentThread().getName());System.out.println(event.getData()+" end seq: "+sequence);}@Overridepublic void onEvent(MsgEvent event) throws Exception {System.out.println(name+"-----start-----");Thread.sleep(1000*10);System.out.println("ThreadName:  "+Thread.currentThread().getName());System.out.println(event.getData());System.out.println(name+"-----end-----");}
}

该消息处理器实现了两个接口,EventHandler接口,该接口实现统一消费一个消息会被所有消费者消费;WorkHandler接口,该接口实现分组消费一个消息只能被一个消费者消费,多消费者轮询处理。

四、Disruptor配置

package com.monika.main.system.mq;import cn.hutool.core.thread.NamedThreadFactory;
import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.Disruptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author:whh* @date: 2024-12-04 20:33* <p></p>*/@Configuration
public class RingBufferConfig {@Beanpublic RingBuffer<MsgEvent> ringBuffer(){NamedThreadFactory threadFactory = new NamedThreadFactory("MsgEvent-",true);EventFactory<MsgEvent> eventFactory = new EventFactory<MsgEvent>() {@Overridepublic MsgEvent newInstance() {return new MsgEvent();}};Disruptor<MsgEvent> disruptor = new Disruptor(eventFactory,1024, threadFactory);//定义两个消费者MsgEventHandler m1 = new MsgEventHandler("m1");MsgEventHandler m2 = new MsgEventHandler("m2");//disruptor.handleEventsWith(m1,m2); //统一消费:一个消息会被所有消费者消费disruptor.handleEventsWithWorkerPool(m1,m2);//分组消费:一个消息只能被一个消费者消费,多消费者轮询处理//disruptor.handleEventsWith(m1).then(m2);   //顺序消费:1、3先并行处理,然后2再处理disruptor.start();//配置多消费者,每个消费者将有单独的线程处理return disruptor.getRingBuffer();}
}

五、消息生产者MsgPublish

package com.monika.main.system.mq;import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.RingBuffer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author:whh* @date: 2024-12-04 20:45* <p></p>*/
@Component
public class MsgPublish {public static void publish(String message){/*** 返回布尔值,表示事件是否发布成功,如果失败可根据此值进行业务逻辑判断*/boolean b = ringBuffer.tryPublishEvent(TRANSLATOR, message);}private static final EventTranslatorOneArg<MsgEvent,String> TRANSLATOR =  new EventTranslatorOneArg<MsgEvent,String>() {@Overridepublic void translateTo(MsgEvent event, long sequence, String arg0) {event.setData(arg0);}};private static RingBuffer<MsgEvent> ringBuffer;@Autowiredpublic  void setRingBuffer(RingBuffer<MsgEvent> ringBuffer) {MsgPublish.ringBuffer = ringBuffer;}
}

六、测试

本次测试使用的是分组模式,可以发现一个消息只能被一个消费者消费,且每个消费者都由单独的线程处理。
在这里插入图片描述

七、总结

本次只是简单的应用disruptor框架实现生产-消费者模式,对于disruptor的原理主要是RingBuffer环形数组,这个咱们后续再进一步研究。

相关文章:

并发框架disruptor实现生产-消费者模式

Disruptor是LMAX公司开源的高性能内存消息队列&#xff0c;单线程处理能力可达600w订单/秒。本文将使用该框架实现生产-消费者模式。一、框架的maven依赖 <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --><dependency><groupId>com.lmax<…...

【Vivado】xdc约束文件编写

随手记录一下项目中学到的约束文件编写技巧。 时序约束 创建生成时钟 参考链接&#xff1a; Vivado Design Suite Tcl Command Reference Guide (UG835) Vivado Design Suite User Guide: Using Constraints (UG903) 通过Clocking Wizard IP创建的时钟&#xff08;MMCM或…...

Redis使用场景-缓存-缓存雪崩

前言 之前在针对实习面试的博文中讲到Redis在实际开发中的生产问题&#xff0c;其中缓存穿透、击穿、雪崩在面试中问的最频繁&#xff0c;本文加了图解&#xff0c;希望帮助你更直观的了解缓存雪崩&#x1f600; &#xff08;放出之前写的针对实习面试的关于Redis生产问题的博…...

概率论相关知识随记

作为基础知识的补充&#xff0c;随学随记&#xff0c;方便以后查阅。 概率论相关知识随记 期望&#xff08;Expectation&#xff09;期望的定义离散型随机变量的期望示例&#xff1a;掷骰子的期望 连续型随机变量的期望示例&#xff1a;均匀分布的期望 期望的性质线性性质期望的…...

【PlantUML系列】序列图(二)

目录 一、参与者 二、消息交互顺序 三、其他技巧 3.1 改变参与者的顺序 3.2 使用 as 重命名参与者 3.3 注释 3.4 页眉和页脚 一、参与者 使用 participant、actor、boundary、control、entity 和 database 等关键字来定义不同类型的参与者。例如&#xff1a; Actor&…...

WPF+MVVM案例实战与特效(三十四)- 日志管理:使用 log4net 实现高效日志记录

文章目录 1、概述2、日志案例实现1、LogHelper 类详解2、代码解释3、配置文件4、实际应用案例场景 1:记录系统运行日志场景 2:记录数据库操作日志场景 3:记录 HTTP 请求日志5、总结1、概述 在WPF软件开发中,良好的日志记录机制对于系统的调试、维护和性能优化至关重要。lo…...

前端测试框架 jasmine 的使用

最近的项目在使用AngulaJs,对JS代码的测试问题就摆在了面前。通过对比我们选择了 Karma jasmine ,使用 Jasmine做单元测试 &#xff0c;Karma 自动化完成&#xff0c;当然了如果使用 Karma jasmine 前提是必须安装 Nodejs。 安装好 Nodejs &#xff0c;使用 npm 安装好必要…...

Qwen2-VL视觉大模型微调实战:LaTex公式OCR识别任务(完整代码)

《SwanLab机器学习实战教程》是一个主打「开箱即用」的AI训练系列教程&#xff0c;我们致力于提供完善的数据集、源代码、实验记录以及环境安装方式&#xff0c;手把手帮助你跑起训练&#xff0c;解决问题。 Qwen2-VL是通义千问团队最近开源的大语言模型&#xff0c;由阿里云通…...

「Mac玩转仓颉内测版42」小学奥数篇5 - 圆和矩形的面积计算

本篇将通过 Python 和 Cangjie 双语解决简单的几何问题&#xff1a;计算圆的面积和矩形的面积。通过这道题&#xff0c;学生将掌握如何使用公式解决几何问题&#xff0c;并学会用编程实现数学公式。 关键词 小学奥数Python Cangjie几何计算 一、题目描述 编写一个程序&#…...

Groom Blender to UE5

Groom Blender to UE5 - Character & Animation - Epic Developer Community Forums Hello, 你好&#xff0c; While exporting my “groom” from blender to UE5, I notice that the curves have a minimal resolution in Unreal. However I would like to get the same …...

开发一套ERP 第十弹 图片作为配置文件,本地读取图片,定时更新图片类型

echo Hello World在同一数据库中在建一个图床数据表,产品一,一对应,图片命名 最优的方案&#xff0c;使用 rust 在构建一个 http server 用于管理非数据库资源,也可以将来对接不同的图床&#xff0c;部署方便 考虑到数据库资源和图片资源,都可以被远程访问这种方法最佳...

第七十六条:努力保持故障的原子性

当对象抛出异常之后&#xff0c;通常我们期望这个对象仍然保持在一种定义良好的可用状态之中&#xff0c;即使失败是发生在执行某个操作的过程中间。对于受检的异常而言&#xff0c;这尤为重要&#xff0c;因为调用者期望能从这种异常中进行恢复。一般而言&#xff0c;失败的方…...

Word分栏后出现空白页解决方法

Word分栏后出现空白页解决方法 只需要在后面的空白页设置相同的页面布局(分栏格式)&#xff0c;然后按Ctrl backspace即可删除该空白页。 参考文章&#xff1a;Word分栏出现空白怎么解决。...

基于HTML和CSS的校园网页设计与实现

摘要 随着计算机、互联网与通信技术的进步&#xff0c;Internet在人们的学习、工作和生活中的地位也变得越来越高&#xff0c;校园网站已经成为学校与学生&#xff0c;学生与学生之间交流沟通的重要平台&#xff0c;对同学了解学校内发生的各种事情起到了重要的作用。学校网站…...

【算法day7】字符串:反转与替换

题目引用 反转字符串反转字符串II替换数字 1.反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&am…...

分布式存储厂商

分布式存储 以下是对分布式存储厂商XSKY星辰天合、IOMesh&#xff08;SmartX&#xff09;、SmartX的深度对比&#xff1a; 1. XSKY星辰天合 产品与服务&#xff1a;XSKY星辰天合提供统一存储平台&#xff0c;支持块、文件和对象存储服务。已为近2400家大型政企机构实施部署&…...

合合信息扫描全能王线下体验活动:科技与人文的完美交融

文章目录 前言签到欢迎仪式产品体验智能高清滤镜去除透字效果照片高清修复 破冰行动会议感受 前言 作为合合信息旗下扫描全能王的忠实粉丝&#xff0c;上周&#xff0c;我很荣幸参与了扫描全能王“扫出你的能量buff”快闪活动及技术交流会。这次活动的不仅让我对这款强大的文档…...

单链表在Go语言中的实现与操作

简介 单链表是一种基本的线性数据结构&#xff0c;由节点组成&#xff0c;每个节点存储数据和指向下一个节点的指针。今天&#xff0c;我们将深入探讨如何在Go语言中实现和操作单链表。 单链表的优缺点 优点&#xff1a; 动态内存分配&#xff0c;灵活性高。插入和删除节点操…...

网关整合sentinel无法读取nacos配置问题分析

sentinel无法读取nacos配置问题分析 1.spring-cloud-gateway整合sentinel2.问题现象3.原因猜测4.源码分析4. 结语 最近公司需要上线一个集约项目&#xff0c;虽然为内网项目&#xff0c;但曾经有过内网被攻破&#xff0c;导致内部系统被攻击的案例&#xff0c;且集约系统同时在…...

简化XPath表达式的方法与实践

XPath表达式用于在XML或HTML文档中定位元素。有时候&#xff0c;XPath表达式可能会变得非常冗长和复杂&#xff0c;这不仅难以阅读和维护&#xff0c;而且也可能影响性能。因此&#xff0c;学会如何简化XPath表达式是非常重要的。本文将介绍几种简化XPath表达式的方法&#xff…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...