由于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中生产者线程与消费者之间的协调的更多相关文章

  1. java线程中生产者与消费者的问题

    一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费 ...

  2. Disruptor框架中生产者、消费者的各种复杂依赖场景下的使用总结

    版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系.网上其他博客 ...

  3. disruptor架构四 多生产者多消费者执行

    1.首先介绍下那个时候使用RingBuffer,那个时候使用disruptor ringBuffer比较适合场景比较简单的业务,disruptor比较适合场景较为复杂的业务,很多复杂的结果必须使用di ...

  4. Storm-源码分析- Disruptor在storm中的使用

    Disruptor 2.0, (http://ifeve.com/disruptor-2-change/) Disruptor为了更便于使用, 在2.0做了比较大的调整, 比较突出的是更换了几乎所有的 ...

  5. 生产者和消费者之间的线程通讯wait()

    生产者与消费者,采用notify()唤醒 package com.dwz.concurrency.chapter9; /** * 生产者和消费者之间的通信问题 * 执行wait()之后锁被释放 */ ...

  6. 从零开始实现lmax-Disruptor队列(一)RingBuffer与单生产者、单消费者工作原理解析

    1.lmax-Disruptor队列介绍 disruptor是英国著名的金融交易所lmax旗下技术团队开发的一款java实现的高性能内存队列框架 其发明disruptor的主要目的是为了改进传统的内存 ...

  7. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  8. [译]线程生命周期-理解Java中的线程状态

    线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...

  9. C#中的线程(三) 使用多线程

    第三部分:使用多线程 1.  单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM——Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留 ...

随机推荐

  1. java常用设计模式十一:策略模式

    一.概述 定义:策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(概念不好理解,可以看第二节的合例子) 基本角色: 环境( ...

  2. C++STL list

    list双向链表 高效进行插入删除数据 不可以随机存取元素,所以不支持at()和[]操作符.it可以++  --,不能it+5 节点序号从0开始 list<int> l; l.push_b ...

  3. UVa 10561 Treblecross (SG函数)

    题意:给定上一行字符串,其中只有 X 和 . 并且没有连续的三个 X,两个玩家要分别在 . 上放 X,如果出现三个连续的 X,则该玩家胜利,现在问你先手胜还是败,如果是胜则输出第一步可能的位置. 析: ...

  4. Keras人工神经网络多分类(SGD)

    import numpy as np import pandas as pd from keras.models import Sequential from keras.layers import ...

  5. android-基础编程-Preference

    由于SDK封装和提供了一套基于Preference的类,使用Preference通过编辑xml配置文件,只要很少的代码就可以实现了,而且Preference本身已经实现了参数保存,不需要我们再考虑将参 ...

  6. How to transfer developer profile to one mac to another mac

    Export developer profile from old mac. In the Xcode Organizer, select your team in the Teams section ...

  7. noip第3课资料

  8. android 按照拼音模糊查询中如何把字符转换成拼音

    http://files.cnblogs.com/liaolandemengxiang/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9.rar 首先转换成的 ...

  9. Scala界面事件处理编程实战详解.

    今天学习了一个Scala界面事件处理编程,让我们从代码出发. import scala.swing._import scala.swing.event._ object GUI_Panel exten ...

  10. redis解决保存快照失败后redis无法写入的问题

    通过关闭配置项stop-writes-on-bgsave-error解决该问题. redis 127.0.0.1:6379> config set stop-writes-on-bgsave-e ...