发送消息时序图

内窥镜消息队列发送消息原理

目的

有一个多线程的Java应用程序,使用消息队列来处理命令

时序图

在这里插入图片描述

@startumlactor User
participant "sendCmdWhiteBalance()" as Controller
participant CommandConsumer
participant MessageQueueUser -> Controller: 调用sendCmdWhiteBalance()Controller -> MessageQueue: 将白平衡命令加入队列
activate MessageQueueController -> CommandConsumer: 等待命令完成
activate CommandConsumerCommandConsumer -> MessageQueue: 从队列中获取命令
MessageQueue -> CommandConsumer: 返回命令
CommandConsumer -> CommandConsumer: 执行命令
CommandConsumer -> Controller: 命令执行完成
deactivate CommandConsumerController -> User: 返回成功响应@enduml

线程安全和性能优化

使用阻塞队列(ArrayBlockingQueue)

使用ArrayBlockingQueue是因为它是一种线程安全的队列数据结构,它在多线程环境中提供了同步。

它的核心原理是基于锁和条件变量,它能够安全地协调不同线程之间的操作,确保数据的正确性。这是在多线程编程中一种重要的工具,它避免了显式的锁管理,降低了错误的可能性,提高了代码的可维护性。

使用blockingQueue.take()

调用blockingQueue.take()的主要目的是防止线程空转(busy-waiting)。

在没有消息进入队列的情况下,如果你使用简单的轮询(如poll()或isEmpty()检查),线程可能会在空循环中浪费大量的CPU时间。而take()方法会使线程在队列为空时进入阻塞状态,直到队列中有数据可以被取出。这降低了线程的 CPU 消耗,有效地减少了开销,使得线程能够更有效地等待新消息。

Java代码

下面是我的代码
@Component
@Slf4j
public class QueueJob {@PostConstructpublic void QueueJob() {log.info("消费者开启****************************************************************************************************");if (System.getProperty("os.name") != null && System.getProperty("os.name").toLowerCase().startsWith("windows")) {return;}log.info("消费者开启");// 创建消息队列 (MessageQueue) 实例和消费者线程 (CommandConsumer)CommandConsumer commandConsumer = new CommandConsumer(messageQueue);commandConsumer.start();}}@Slf4j
public class CommandConsumer extends Thread {private final MessageQueue messageQueue;public CommandConsumer(MessageQueue messageQueue) {log.info("放入参数");this.messageQueue = messageQueue;}@Overridepublic void run() {log.info("进入消费者模块中***********************************");while (true) {/*** 初始化完成后在执行命令* @author lst* @date 2023/8/8 9:18*/if (!initStatus.get()) {continue;}log.info("run****************************************");CommandQueue commandQueue;try {commandQueue = messageQueue.takeFromQueue();} catch (InterruptedException e) {throw new RuntimeException(e);}if (commandQueue != null) {// 调用 sendMsg 方法发送指令,等待响应成功try {log.info("sendMsg***********************************");sendMsg(commandQueue.getCommand());log.info("success***********************************");} catch (Exception e) {catchSendMsgException(commandQueue.getMethod(), e);} finally {handleCountDownLatch(commandQueue.getMethod());}}}}@Slf4j
public class MessageQueue {/*** 顺序发送* 有应答才能发送下一条指令** @author lst* @date 2023/8/7 13:45* @param null* @return null*/private final BlockingQueue<CommandQueue> blockingQueue = new ArrayBlockingQueue<>(30, true);public void addToQueue(CommandQueue c) {log.info("添加队列中" + c.toString());if (!blockingQueue.offer(c)) {throw new IllegalStateException("队列已满,无法接受新的指令");}}public CommandQueue takeFromQueue() throws InterruptedException {return blockingQueue.take();}public int getQueueFreeSize() {return blockingQueue.remainingCapacity();}
}基于上面我调用白平衡接口,会先将白平衡命令加入到阻塞队列中,阻塞队列中while循环持续消费@Operation(summary = "白平衡")@ConcurrentControl@GetMapping("sendCmdWhiteBalance")public CommonResult sendCmdWhiteBalance() throws InterruptedException {String key = WHITEBALANCE;messageQueue.addToQueue(new CommandQueue("sendCmdWhiteBalance", key));cmdWhiteBalanceCountDownLatch.await();cmdWhiteBalanceCountDownLatch = new CountDownLatch(1);if (cmdWhiteBalanceCountDownLatchException != null) {Exception e = cmdWhiteBalanceCountDownLatchException;cmdWhiteBalanceCountDownLatchException = null;throw new RuntimeException(e);}return CommonResult.success();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/156096.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据库】Sql Server数据迁移,处理自增字段赋值

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 在实际项目开发中&#xff0c;如果遇到高版本导入到低版本&#xff0c;或者低版本转高版本&#xff0c;那么就会出现版本不兼容无法导入&#xff0c;此时通过程序遍历创建表和添加数据方式…

开源音乐播放器!

导读音乐是生活的一部分。维基百科关于音乐发展历史的文章有这样一段不错的描述说&#xff1a;“全世界所有的人们&#xff0c;包括哪怕是最孤立、与世隔绝的部落&#xff0c;都会有自己的特色音乐……”好吧&#xff0c;我们开源人就构成了一个部落。我建议我们的“音乐形式”…

TCP/IP(十四)流量控制

一 流量控制 说明&#xff1a; 本文只是原理铺垫,没有用tcpdumpwiresahrk鲜活的案例讲解,后续补充 ① 基本概念 流量控制: TCP 通过接受方实际能接收的数据量来控制发送方的窗口大小 ② 正常传输过程 背景:1、客户端是接收方,服务端是发送方 --> 下载2、假设接收窗…

基于Vue+ELement实现增删改查案例与表单验证

目录 前言 一、增删改查案例的实现 1.查询 2.增加 3.修改 4.删除 5.增删改查效果演示 二、表单验证 1.在官网中找到表单---表单验证 2.定义规则 3.使用规则 前言 Element UI是一款基于Vue.js的组件库&#xff0c;提供了丰富的组件和功能&#xff0c;包括表单、按钮、…

mysql面试题28:MySQL的主从复制模式、MySQL主从复制的步骤、MySQL主从同步延迟的原因、MySQL主从同步延迟的解决办法

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:简单讲一下MySQL的主从复制模式 MySQL的主从复制(Master-Slave Replication)是一种数据库复制技术,用于将一个MySQL数据库服务器(主服务器)的…

nodejs+vue+elementui养老院老年人服务系统er809

“养老智慧服务平台”是运用nodejs语言和vue框架&#xff0c;以MySQL数据库为基础而发出来的。为保证我国经济的持续性发展&#xff0c;必须要让互联网信息时代在我国日益壮大&#xff0c;蓬勃发展。伴随着信息社会的飞速发展&#xff0c;养老智慧服务平台所面临的问题也一个接…

嵌入式面试常见问题(一)

目录 1.什么情况下会出现段错误&#xff1f; 2.swap() 函数为什么不能交换两个变量的值 3.一个函数有六个参数 分别放在哪个区&#xff1f; 4.定义一个变量&#xff0c;赋初值和不赋初值分别保存在哪个区&#xff1f; 5.linux查看端口状态的命令 6.结构体中->和.的区…

uniapp:幸运大转盘demo

<template><view class"index"><image src"../../static/img/158.png" mode"" class"banner"></image><view class"title">绿色积分加倍卡拿到手软</view><almost-lottery :lottery…

使用 L293D 电机驱动器 IC 和 Arduino 控制直流电机

如果您打算组装新的机器人朋友&#xff0c;您最终会想要学习如何控制直流电机。控制直流电机最简单且经济的方法是将 L293D 电机驱动器 IC 与 Arduino 连接。它可以控制两个直流电机的速度和旋转方向。 此外&#xff0c;它还可以控制单极步进电机&#xff08;如 28BYJ-48&#…

邮政编码,格式校验:@ZipCode(自定义注解)

目标 自定义一个用于校验邮政编码格式的注解ZipCode&#xff0c;能够和现有的 Validation 兼容&#xff0c;使用方式和其他校验注解保持一致&#xff08;使用 Valid 注解接口参数&#xff09;。 校验逻辑 有效格式 不能包含空格&#xff1b;应为6位数字&#xff1b; 不校验…

区块链在游戏行业的应用

区块链技术在游戏行业有许多潜在的应用&#xff0c;它可以改变游戏开发、发行和玩家交互的方式。以下是区块链技术在游戏行业的一些主要应用&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.游戏资产…

L05_SpringBoot入门

SpringBoot入门 浅谈Restful风格代码实现(并且通过Apifox进行接口测试[以传入json格式数据为例])首先创建一个SpringBoot项目,pom文件包引入如下下面在新建src创建com.ndky.controller包,然后再在包内创建一个HelloController类编写(一个简易的restful风格的代码)编写GET请求代…

智能工厂:APS高级计划排程系统成为了制造业建设智能工厂的核心必要需求

近年来&#xff0c;中国经济受到了许多因素的影响&#xff0c;例如新冠疫情冲击和国内外经济环境的巨大变化&#xff0c;随着我国人口红利的减少和人力成本逐步的增加&#xff0c;不论是中大型或小微制造企业为了提高市场竞争力并降低生产成本&#xff0c;都纷纷开始规划建设数…

C++QT-day6

/*定义一个基类 Animal&#xff0c;其中有一个虛函数perform&#xff08;)&#xff0c;用于在子类中实现不同动物的表演行为。*/ #include <iostream> using namespace std; class Animal //封装Animal类&#xff08;基类&#xff09; { private:string person; public:A…

Linux内存管理 (2):memblock 子系统的建立

前一篇&#xff1a;Linux内存管理 (1)&#xff1a;内核镜像映射临时页表的建立 文章目录 1. 前言2. 分析背景3. memblock 简介3.1 memblock 数据结构3.2 memblock 接口 4. memblock 的构建过程 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者…

Vue绑定样式

一、绑定class样式 语法格式&#xff1a; :class "属性名" &#xff08;一&#xff09;字符串写法 该写法适用于样式的类名不确定&#xff0c;需要动态指定的场景 我们用如下的CSS样式进行操作演示 我们要完成点击按钮改变CSS样式的操作&#xff0c;如下图代码所…

C# 中大小端Endian

大小端可以找下资料很多&#xff0c;都是文字的。我每次遇到大小端问题就会搜资料&#xff0c;总是记不住。我自己用用图片记录一下&#xff0c;以备直观的从内存中看到。 在C#中可以用BitConverter.IsLittleEndian来查询。 几个数字在内存中 我们来观察一下&#xff0c;我的…

js获取当前时间

// 格式化日对象 (获取当前时间) export function timeFormat() {var date new Date();var sign2 ":";var year date.getFullYear(); // 年var month date.getMonth() 1; // 月var day date.getDate(); // 日var hour date.getHours(); // 时var minutes dat…

Burstormer论文阅读笔记

这是CVPR2023的一篇连拍图像修复和增强的论文&#xff0c;一作是阿联酋的默罕默德 本 扎耶得人工智能大学&#xff0c;二作是旷视科技。这些作者和CVPR2022的一篇BIPNet&#xff0c;同样是做连拍图像修复和增强的&#xff0c;是同一批。也就是说同一个方向&#xff0c;22年中了…

RecyclerView 空白区域点击事件

在项目中使用RecyclerView展示列表数据&#xff0c;用了GridLayoutManager&#xff0c;在遇到item个数不满足一行时&#xff0c;会在页面右侧透出空白位&#xff0c; 如下图所示. 目前点击空白位是没有点击响应事件的&#xff0c;我们想实现点击响应以扩大用户可以进入LandingP…