用Disruptor框架实现生产者-消费者模式

ConcurrentLinkedQueue队列的秘诀就在于大量使用了无锁CAS操作。
现成的Disruptor框架实现CAS进行编程。
无锁的缓存框架:Disruptor
它使用无锁的方式实现了一个环形队列,非常适合实现生产者-消费者模式,
比如事件和消息的发布。如果队列是环形的,则只需要对外提供一个当前位置cursor,
利用这个指针即可用进入队操作,也可用进行出队操作。
由于环形队列的缘故,队列的总大小必须事先指定,不能动态扩展。
为了能够快速从一个序列对于到数组的实际位置,每次有元素入队,序列就加1.
Disruptor框架要求我们必须将数组的大小设置为2的整数次方。这样通过sequence&(queueSize-1)
就能立即定位到实际的元素位置index,这比取余%操作快得多。
如果搭建不理解上面的sequence&(queueSize-1),那么我在这里再简单说明一下。
如果queueSize是2的整数次幂。则这个数字的二进制表示必然是10、100、1000、10000等形式。

果一个数字是2的整数次幂,其二进制表示的确是形如10、100、1000、10000等的形式。
这是因为2的整数次幂在二进制中只有一个比特位为1,其余都为0。例如:
2^1 = 2,二进制表示为10
2^2 = 4,二进制表示为100
2^3 = 8,二进制表示为1000
2^4 = 16,二进制表示为10000
这种规律一直持续下去。这样的性质在计算机科学和计算机工程中经常会被利用,
特别是在处理队列(Queue)等数据结构的大小时。
Disruptor框架


生产者需要一个 RingBuffer的引用,也就是环形缓冲区。
它有一个重要的方法pushData()将产生的数据推入缓冲区。
方法pushData()接收一个ByteBuffer对象。在ByteBuffer对象中
可用用来包装任何数据类型。这里用来存储long整数,
pushData()方法的功能就是将传入的ByteBuffer对象中的数据提取出来,
并转载到环形缓冲区中。
只有发布后的数据才会真正被消费者看见。

public class Consumer implements WorkHandler<PCData> {@Overridepublic void onEvent(PCData event) throws Exception{System.out.println(Thread.currentThread().getId()+":Event: --"+ event.get() * event.get() +"--");}}
public class PCData {private long value;public void set(long value){this.value = value;}public long get(){return value;}}
public class PCDataFactory implements EventFactory<PCData> {public PCData newInstance(){return new PCData();}
}
public class Producer {private final RingBuffer<PCData> ringBuffer;public Producer(RingBuffer<PCData> ringBuffer){this.ringBuffer = ringBuffer;}public void pushData(ByteBuffer bb){long sequence = ringBuffer.next();try{PCData event = ringBuffer.get(sequence);event.set(bb.getLong(0));}finally {ringBuffer.publish(sequence);}}}
public static void main(String[] args) {Executor executors =  Executors.newCachedThreadPool();PCDataFactory factory = new PCDataFactory();int bufferSize = 1024;Disruptor<PCData> disruptor = new Disruptor<PCData>((EventFactory<PCData>) factory,bufferSize,(Executor) executors,ProducerType.MULTI,new BlockingWaitStrategy());disruptor.handleEventsWithWorkerPool(new Consumer(),new Consumer(),new Consumer(),new Consumer());disruptor.start();RingBuffer<PCData> ringBuffer = disruptor.getRingBuffer();Producer producer = new Producer(ringBuffer);ByteBuffer bb = ByteBuffer.allocate(8);for(long l = 0;true;l++){bb.putLong(0,l);producer.pushData(bb);try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("add data "+ l);}}

main 函数是一个无限循环,因为它包含了一个 for 循环,其中的条件是 true。因此,这个 main 函数会一直执行下去,直到程序被手动中断或出现异常导致程序终止。

在循环中,你不断地向 RingBuffer 中发布数据,由 Producer 类的 pushData 方法完成。同时,RingBuffer 中的数据会被多个消费者(Consumer 类)并发地处理。

你在循环中使用了 Thread.sleep(100),这会导致每次循环执行后线程暂停 100 毫秒。因此,每次数据被发布后,你会看到 "add data" 的输出,并且在消费者的 onEvent 方法中会输出相应的信息。

由于这是一个生产者-消费者模型,生产者生产数据,消费者处理数据,程序在生产和消费之间持续运行。

如果你希望在某个条件下结束程序,你需要在循环中添加相应的退出条件,并在满足条件时使用 break 语句跳出循环。否则,这个程序将一直执行下去。

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

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

相关文章

Opencv_CUDA实现推理图像前处理与后处理

Opencv_CUDA实现推理图像前处理与后处理 通过trt 或者 openvino部署深度学习算法时&#xff0c;往往会通过opencv的Mat及算法将图像转换为固定的格式作为输入openvino图像的前后处理后边将在单独的文章中写出今晚空闲搜了一些opencv_cuda的使用方法&#xff0c;在此总结一下前…

2023-12-25 事业-代号s-shein分析

前阵子SHEIN看的比较多,几乎把市面上的报告和趋势都研究了下,总结了这篇关于SHEIN的一切,从0开始全面的了解下SHEIN,比较通俗易懂,可以看看。 如果你还不了解SHEIN这家公司,想知道知道,可以翻看下,快速get这家公司的点如果你想了解下这家公司怎么发展和快速提升的,可以…

【大厂面试】之 美团(一面经含答案)

美团 一面 tcp三次握手&#xff0c;四次挥手。time-wait、close-wait状态。MSL代表什么&#xff1f;为什么time-wait是2MSL&#xff0c;可不可以更长&#xff1f;如果不设置time-wait有什么影响 time-wait是主动关闭方的一个状态&#xff1b;close-wait是被动关闭方的一个状态…

详细学习Java注解Annotation、元注解(通俗易懂,一学就会)

概述 底层原理 自定义注解 示例代码&#xff1a; 1. 2.只有属性名为value的才可以&#xff0c;java对它进行了标识&#xff0c;如果是其他别名如value1是不行的 3.多个属性&#xff0c;必须用键值对形式&#xff0c;不能少写&#xff0c;也不能多写&#xff0c;除非有default修…

阻抗控制中的弹簧与阻尼影响分析

阻抗控制是一种机器人控制方法&#xff0c;通过调整机器人的阻抗来实现对机器人的精准控制。在阻抗控制中&#xff0c;弹簧和阻尼是两个重要的参数&#xff0c;它们对机器人的性能和稳定性有很大的影响。 弹簧代表机器人的刚度和弹性&#xff0c;而阻尼代表机器人的阻尼特性&a…

OpenGL :LearnOpenGL笔记

glfw https://github.com/JoeyDeVries/LearnOpenGL/blob/master/src/1.getting_started/1.1.hello_window/hello_window.cpp #include <glad/glad.h>// 注: GLAD的include文件包含所需的OpenGL头文件(如GL/GL.h) &#xff0c;因此确保在其他需要OpenGL的头文件 (如GLFW…

iEnglish:家长陪伴阅读有助于孩子阅读兴趣养成

在家庭教育畅销书《妈妈教的数学》中,作者孙路弘描述称,自己小学四年级时,家里买了一杆秤,这杆秤很快成了他的玩具,被拿来称各种各样的东西,书包、水杯,家里所有10斤以内的东西都被他称过了。 这玩这杆秤的过程中,他开始思考东西的“重量”到底是什么?为什么小小的秤砣可以称…

智能优化算法应用:基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.厨师算法4.实验参数设定5.算法结果6.参考文献7.MA…

【Java JVM】Java 实例对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。 但是 reference 类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用, 并没有定义这个引用应该通过什么方式去定位, 访问到堆中对象的具体位置, 所以对象访问方式也是由虚拟机实现而定的&#xff0c;主流…

视频搜索AI平台,输入关键词全网查找相关内容

体验网站链接&#xff1a;https://avse.vercel.app GitHub网站链接&#xff1a;GitHub - yoeven/ai-video-search-engine 原文地址&#xff1a;视频搜索AI平台&#xff0c;输入关键词全网查找相关内容-喜好儿aigc 这个平台允许用户通过类似自然语言的查询方式搜索视频&#x…

数字化协同在服装行业:监狱服装生产的量身解决方案

内容来自演讲&#xff1a;苗子实 | 北京宜通华瑞科技有限公司 | 产品经理 摘要 这篇文章介绍了宜通世纪子公司北京宜通华瑞在服装行业智能制造方面的业务&#xff0c;以及明道云提供的业务支持。文章提到了服装行业的痛点及解决方案&#xff0c;并详细介绍了优化监狱服装企业的…

算法训练第四十八天|198. 打家劫舍、213. 打家劫舍 II、337. 打家劫舍 III

198. 打家劫舍&#xff1a; 题目链接 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报…