Rabbitmq消息顺序的问题以及解决方案

1.1消息顺序的场景

场景1:一个queue,多个consumer

一个queue,有多个consumer去消费,这样就会造成顺序的错误,consumer从MQ里面读取数据是有序的,但是每个consumer的执行时间是不固定的,无法保证先读到消息的consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。,

人话就是:我确实保证了消息是按按顺序接的。但是由于每一个消息执行的是时间不一样。如果我前面的执行消息比较长,会导致我后面的操作比前面的操作更早执行。就出现了顺序错误

 consumer多线程消费

一个queue对应一个consumer,但是consumer里面进行了多线程消费,这样也会造成消息消费顺序错误。

人话:就是线程的执行是强制式的,你永远不知道下一个执行的会是哪个指令。

2.解决方案:

单消费者、单线程消费就行。

如果你非要多线程,你可以参考下,多线程输出a,b,c

 

/**
 * @author XDarker
 * 2018-5-17
 */
public class Main {
	
	public static void main(String[] args) throws InterruptedException {
		
		int num = 1;//当前正在执行线程的标记
		ABCPrint print = new ABCPrint(num); 
		
		Thread threadA = new Thread(new RunnableA(print));
		Thread threadB = new Thread(new RunnableB(print));
		Thread threadC = new Thread(new RunnableC(print));
		threadA.start();
		Thread.sleep(500);
		threadB.start();
		Thread.sleep(500);
		threadC.start();
	}
}
class RunnableA implements Runnable{
	
	private ABCPrint print;
	public RunnableA(ABCPrint print) {
		super();
		this.print = print;	
	}
 
	@Override
	public void run() {		
		print.PrintA();
		
	}
}
class RunnableB implements Runnable{
	
	private ABCPrint print;
	public RunnableB(ABCPrint print) {
		super();
		this.print = print;
	}
 
	@Override
	public void run() {		
		print.PrintB();
	}
}
class RunnableC implements Runnable{
	
	private ABCPrint print;
	public RunnableC(ABCPrint print) {
		super();
		this.print = print;
	}
 
	@Override
	public void run() {		
		print.PrintC();
	}
}
class ABCPrint {
 
	private int num;//当前正在执行线程的标记
	public ABCPrint(int num) {
		super();
		this.num = num;
	}
	
	
	public void PrintA(){
		for (int j = 0; j < 2; j++)//表示 循环打印2轮
		synchronized(this){
	              while(num != 1){
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for (int i = 0; i < 3; i++) {//表示 打印3次
				System.out.println("A");  
			}
			
		    //打印A线程执行完 ,通知打印B线程
                    num = 2;  
                    this.notifyAll();  
	        }
	}
	
	public void PrintB(){
		for (int j = 0; j < 2; j++)//表示 循环打印2轮
		synchronized(this){
			while(num != 2){
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for (int i = 0; i < 2; i++) {//表示 打印2次
				System.out.println("B");  
			}
		    //打印B线程执行完 ,通知打印C线程
                    num = 3;  
                    this.notifyAll();  
		}
	}
	
	public void PrintC(){
		for (int j = 0; j < 2; j++)//表示 循环打印2轮
		synchronized(this){
			while(num != 3){
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
	            System.out.println("C");  
	            //打印C线程执行完 ,通知打印A线程
                    num = 1;  
                    this.notifyAll();  
		}
	}	
}	

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1-28 核心类库(四)

一 BigDecimal类(会用) 1.作用:用来进行金融类项目中的数据的精确计算 2. import java.math.BigDecimal; import java.math.RoundingMode;public class BigDecimalTest {public static void main(String[] args) {//一定要字符串 int类型的答案不一定准BigDecimal bd1new B…

专题二_滑动窗口(1)

目录 209. 长度最小的子数组 解析 题解 3. 无重复字符的最长子串 解析 题解 1004. 最大连续1的个数 III 解析 题解 209. 长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 解析 题解 class Solution { public:int minSubArrayLen(int…

JAVA WEB 能够实现整个文件夹的上传下载吗?

导入项目&#xff1a; 导入到Eclipse&#xff1a;导入项目 导入到IDEA&#xff1a;导入项目 springboot统一配置&#xff1a;springboot-配置 下载示例&#xff1a; https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/ 工程 NOSQL NOSQL示例不需要任何配置&#xff0c;可…

【Java程序员福音】国外Java 程序员开发常用的工具(全)

Java是一门开源语言&#xff0c;所以可以选择的开发环境很多&#xff0c;你适合哪一个呢&#xff1f;整理了一些Java程序员开发常用的工具&#xff0c;需要的同学可以收藏。 1、免费开源Eclipse Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环…

深入浅出:探索Hadoop生态系统的核心组件与技术架构

目录 前言 HDFS Yarn Hive HBase Spark及Spark Streaming 书本与课程推荐 关于作者&#xff1a; 推荐理由&#xff1a; 作者直播推荐&#xff1a; 前言 进入大数据阶段就意味着 进入NoSQL阶段&#xff0c;更多的是面向OLAP场景&#xff0c;即数据仓库、BI应用等。 …

【Ubuntu】Ubuntu LTS 稳定版更新策略

1、确保下载环境 sudo apt update && sudo apt upgrade -y sudo apt autoremove 2、安装更新管理器 sudo apt install update-manager-core -y 3、设置只更新稳定版 sudo vim /etc/update-manager/release-upgrades 4、开始更新&#xff0c;耐心等待 sudo do-re…

iOS开发进阶(十):viewController生命周期讲解

文章目录 一、生命周期二、注意事项案例讲解 一、生命周期 viewController有自己的生命周期&#xff0c;其生命周期如下图&#xff1a; init - 初始化程序&#xff1b;loadView - 在UIViewController对象的view被访问且为空的时候调用&#xff1b;viewDidLoad - 视图加载完成后…

C语言例4-28:求两个正整数的最大公约数。

算法分析&#xff1a; 输入两个正整数m和nm%n 的余数 r&#xff0c;然后 mn;nr;当 n0, 则m是最大公约数&#xff0c;算法结束&#xff1b;否则转至执行2&#xff0c;重复上述过程&#xff0c;直到n0为止 代码如下&#xff1a; //求两个正整数的最大公约数。 #include<std…

语落AI论文助手-轻松降重加素材,让论文写作更加简单高效

今天给大家推荐一款AI论文写作工具&#xff1a;语落AI论文助手。 语落AI论文助手是一款专业的AI论文写作工具&#xff0c;它最大的特色是支持论文素材查询&#xff0c;论文内容改写&#xff0c;可以高效生成论文内容&#xff0c;轻松给论文降重。 它的网址是&#xff1a;语落-…

LeetCode hot100-20

48. 旋转图像给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。这题说了不能用辅助矩阵&#xff0c;但是不辅助我做不出来。还是暴力解…

如何借用 NTFS 交换数据流 实现隐藏文件?如何使用【文件包含】PHP伪协议?不同操作系统如何实现文件隐藏和木马伪装?

如何借用 NTFS 交换数据流 实现隐藏文件?如何使用【文件包含】PHP伪协议?不同操作系统如何实现文件隐藏和木马伪装? NTFS交换数据流(Alternate Data Streams, ADS)是NTFS文件系统特有的一种功能,它允许在同一个文件名下存储多个数据流。除了默认的数据流(通常用于存储文…

Wi-Fi 标准的演进

在数字时代的今天&#xff0c;Wi-Fi已经成为了我们生活中不可或缺的一部分&#xff0c;但这一无线通信技术的演进却是一个精彩而丰富的历程。从最初迈出的第一步&#xff0c;到如今的Wi-Fi 7高速数据传输&#xff0c;每一个Wi-Fi标准的诞生都伴随着无数创新和技术的突破。 802.…

Web漏洞--WAF绕过+堆叠查询

Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql语句(多条)一起执行。而在真实的运用中也是这样的&#xff0c;我们知道在mysql 中&#xff0c;主要是命令行中&#xff0c;每一条语句结尾加;表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做…

Cornflakes: Zero-Copy Serialization for Microsecond-Scale Networking——论文泛读

SOSP 2023 Paper 论文阅读笔记整理 问题 数据序列化对于许多数据中心应用程序来说至关重要&#xff0c;序列化的主要开销在于数据移动&#xff0c;将应用程序数据移动到数据包中所需的内存拷贝成本高昂。最近的零拷贝API暴露了NIC分散收集功能&#xff0c;增加了将数据移动卸…

vant4的dialog、toast不显示样式记录

使用的是按需加载&#xff0c;就是这个 插件会自动帮我们把组件加载上去&#xff0c;但是对于函数式的组件&#xff0c;比如dialog&#xff0c;toast这样的&#xff0c;就会显示的时候没有样式&#xff0c;类似这样 这是因为没有加载对应插件的样式&#xff0c;需要手动加载进来…

Java:反射 reflection ( 概念+相关类+使用方法)

文章目录 一、反射(reflection)1.概念优点&#xff1a;缺点 2.反射的相关类1.Class类1.**反射机制的起源**2.获得类相关的方法3.获得类中属性的相关方法4.获得类中注解相关的方法5.获得类中构造器相关的方法6.获得类中方法相关的方法 2.获取Class对象的三种方法&#xff1a;1.使…

python--冒泡排序和main函数

1.判断是不是回文数&#xff1a; x int(input("请输入一个正整数&#xff1a;")) x str(x) if x x[::-1]:print("是回文数。") else:print("不是回文数。") 2.冒泡排序 # 冒泡排序: # [30&#xff0c;8&#xff0c;-10&#xff0c; 50&am…

【技巧】PyTorch限制GPU显存的可使用上限

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 从 PyTorch 1.4 版本开始&#xff0c;引入了一个新的功能 torch.cuda.set_per_process_memory_fraction(fraction, device)&#xff0c;这个功能允许用户为特定的 GPU 设备设置进程可使用的显存上限比例。 测试代…

从抛硬币试验看概率论的基本内容及统计方法

一般说到概率&#xff0c;就喜欢拿抛硬币做例子。大多数时候&#xff0c;会简单认为硬币正背面的概率各为二分之一&#xff0c;其实事情远没有这么简单。这篇文章会以抛硬币试验为例子并贯穿全文&#xff0c;引出一系列概率论和数理统计的基本内容。这篇文章会涉及的有古典概型…

后端前行Vue之路(二):模版语法之插值与指令

1.概述 Vue.js的模板语法是一种将Vue实例的数据绑定到HTML文档的方法。Vue的模板语法是一种基于HTML的扩展&#xff0c;允许开发者将Vue实例中的数据绑定到HTML元素&#xff0c;以及在HTML中使用一些简单的逻辑和指令。Vue.js 基于 HTML 的模板语法允许开发者声明式地将 DOM 绑…