【disruptor】2、disruptor中生产者线程与消费者之间的协调
由于ringbuffer是一个环形的队列,那么生产者和消费者在遍历这个队列的时候,如何制衡呢?
1、生产快,消费慢,数据丢失?
生产者速度过快,导致一个对象还没消费完,就循环生产了一个新的对象要加入ringbuffer,导致消费不完整,造成数据丢失?
我们注意到,在我们获取生产者下一个位置的时候,是通过ringbuffer的next方法,而这个next方式是调用了sequencer的next方法


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这个对象,在我们创建disruptor对象的时候,创建的



所以这个ringbuffer就是disruptor中的sequencer对象,那么在进行获取next的时候,这里是如何获取下一个的呢?是否会对这个生产获取下一个序列进行相应的等待策略,避免产生相应的干扰!!!
这个各位看官还需多看看里面的代码以及封装(特别是封装,真是九转十八弯),多熟悉,我这绕着绕着很容易就绕晕了,刚开始也是云里雾里。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
回归主线,继续看看next方法
long nextSequence = nextValue + n; 这个标识这次要生产的数据到什么位子
long wrapPoint = nextSequence - bufferSize; 是否超出范围,第一次是没有超出最开始的ringbuffer大小,第二次就是判断是否要对没有被消费的部分进行覆盖了
long cachedGatingSequence = this.cachedValue; 这个是消费者消费的情况,判断从哪里开始到当前位置是没有被消费的

那么这个判断条件是什么意思呢?
wrapPoint > cachedGatingSequence 这个条件是判断,当前超出的部分是否会覆盖到还未被消费的部分数据
cachedGatingSequence > nextValue 这个判断是,未被消费的位置开始,是否在下一个生产者位置的前面,
如果还未被消费的标识比下一个要被生产的位置还小,那说明生产在消费的前面,消费者可以继续消费
如果未被消费的标识比下一个要生产的位置还大,消费盘跑到生产前面了,会造成重复消费
由于是环形的队列,当消费者和生产者同时启动的时候,而cachedValue ,nextValue 是累加计数的,那么我们要保证生产者不能超过消费者一个ringbuffer的大小,不然会产生消费数据丢失
所以,nextValue + 当前要生产的数据 - ringbuffersize 要保证比未被消费的地方小,不然超出到消费者前面一圈,那么部分还没有被消费就又被从新设置了
2、生产慢,消费快,数据重复消费?
生产者速度过慢,导致消费者消费一圈了,生产者还没有生产新的数据出来,会不会导致重复消费?
这里的关键就是两个变量
cachedValue 和 nextValue
cachedValue 进行累加统计被消费的个数,可以记录消费到哪里了的位置
nextValue 进行记录累加统计被生产的位置,可以记录生产到那个位置了
通过这两个变量保证消费的进度永远保持在生产的进度后面,也就是 cachedValue < nextValue 的时候才可以继续生产和消费,违背这个规则就要对一方进行阻塞,或者自旋
总结:

【disruptor】2、disruptor中生产者线程与消费者之间的协调的更多相关文章
- java线程中生产者与消费者的问题
一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费 ...
- Disruptor框架中生产者、消费者的各种复杂依赖场景下的使用总结
版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系.网上其他博客 ...
- disruptor架构四 多生产者多消费者执行
1.首先介绍下那个时候使用RingBuffer,那个时候使用disruptor ringBuffer比较适合场景比较简单的业务,disruptor比较适合场景较为复杂的业务,很多复杂的结果必须使用di ...
- Storm-源码分析- Disruptor在storm中的使用
Disruptor 2.0, (http://ifeve.com/disruptor-2-change/) Disruptor为了更便于使用, 在2.0做了比较大的调整, 比较突出的是更换了几乎所有的 ...
- 生产者和消费者之间的线程通讯wait()
生产者与消费者,采用notify()唤醒 package com.dwz.concurrency.chapter9; /** * 生产者和消费者之间的通信问题 * 执行wait()之后锁被释放 */ ...
- 从零开始实现lmax-Disruptor队列(一)RingBuffer与单生产者、单消费者工作原理解析
1.lmax-Disruptor队列介绍 disruptor是英国著名的金融交易所lmax旗下技术团队开发的一款java实现的高性能内存队列框架 其发明disruptor的主要目的是为了改进传统的内存 ...
- C#中的线程(二) 线程同步基础
1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...
- [译]线程生命周期-理解Java中的线程状态
线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...
- C#中的线程(三) 使用多线程
第三部分:使用多线程 1. 单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM——Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留 ...
随机推荐
- 在vue或者react中使用express框架
在react 或者 vue项目中使用express框架 1.创建vue或者 react 项目 2.在项目中创建server文件夹,创建server.js //require()方法引入express模 ...
- windows下 python2 和python3 共存
目前我们在国内网站上看到的两者共存的方法就是将其中一个的python.exe重命名.虽说在一定程度上可行,但存在一个重大的隐患,就是修改了名字的那个python对应的pip将无法使用. 下面说一下具体 ...
- IE 8 浏览器 F12 调试功能无法使用
“按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的缩略图上,右键-最大化,工具就全 ...
- Win10通知区域图标设置;windows10系统图标合并;Windows10系统通知合并
1.一直喜欢Windows7的通知图标合并 2.通过查阅找到方法 a.输入命令语句 win+R :shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9} 回 ...
- 30条SQL查询优化原则
在我们平常的SQL查询中,其实我们有许多应该注意的原则,以来实现SQL查询的优化,本文将为大家介绍30条查询优化原则. 首先应注意的原则 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 wher ...
- 【1】jQuery异步(Ajax)操作之JSONP [转]
前言: 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域 ...
- 待了解概念_GraphicsView
Linux 的 KDE 是建立在 Graphics view基础上的. 新版本KDE 有向QML前移的趋势. Graphics View 使用了BSP 树的结构. Graphics View 是一个基 ...
- 项目管理系统Redmine(v1.1.2)安装手记
一.环境 1.硬件 普通PC. 2.软件 Windows 2003操作系统. 二.下载必要的软件 1.Ruby 1.8.x Redmine是基于Ruby On Rails的软件,所以首 ...
- noip第5课资料
- 第88讲:Scala中使用For表达式实现map、flatMap、filter
今天我们来学习一下如何使用for表达式实现map.flatMap以及filter 首先,我们来看下map.map的功能是,传入一个list,通过一个函数f,将list中的元素A变成元素B的过程.最后得 ...