源码RingBuffer(一)——生产者猫毛·波拿巴

同样是修改数据,一个采用加锁的方式保证原子性,一个采用CAS的方式保证原子性。

都是能够达到目的的,但是常用的锁(例如显式的Lock和隐式的synchonized),都会把获取不到锁的线程挂起,相对于CAS的不挂起,多了挂起和唤醒的开销。

题外话:CAS与锁的关系

CAS只是在这个场景下,比使用锁来得更纯粹,因为只做数据更新,所以开销更少。但是业务上为了保证一系列操作的原子性,还是要使用锁的。而且锁的底层实现,也依赖于类似于CAS这样的原子性操作。

别的帖子都说RingBuffer中不维护尾指针,尾指针由消费者维护(所谓维护指针,就是修改、移动指针)其实这一句话有点误导性,如果RingBuffer不知道尾部在哪里,那它的数据存储肯定就会出问题,例如把还没消费过的数据给覆盖了。

确实,消费者会自行维护自己的消费指针(消费者指针是消费者消费过的最后一条数据的序号,下一篇中会详细讲到),RingBuffer也不会去干涉消费者指针的维护,但是它会引用所有消费者的指针,读取他们的值,以此作为“尾部”的判断依据。实际上就是最慢的那个消费者作为边界

我们直接来看代码,这个是RingBuffer的publishEvent方法,我们看到,它首先取得一个可用的序列号,然后再将数据放入该序列号的对应位置中。

@OverridepublicvoidpublishEvent(EventTranslatortranslator){//1.先通过原子操作,得到一个可用的序号finallongsequence=sequencer.next();//2.将该序号对应位置的元素进行转换,接着发布translateAndPublish(translator,sequence);}我们来看看这个序列号是如何取得的。我们先看Sequencer的SingleProducerSequencer实现。这里就是判断如果生产者新指针的位置是否会超过尾部,如果超过尾部就挂起片刻,后续再尝试(生产者的等待方式是固定的,不像消费者有一个等待策略)

这里附上几个图可能更好理解:(右边是后续补充的用“画图”画的,对单元格添加一些颜色进行区分)

情况1:队列已满,生产者尝试使用新序号14,但由于(14-8=6),由于最慢的消费者目前消费的最后一条数据的序号是5,5号之后的数据还没被消费,6>5,所以序号14还不能用。生产者线程挂起,下次再次尝试。

情况2:消费者1消费了序号6的数据。(14-8=6)不大于6,这时序号14可用,生产者得到可用的序号。

RingBuffer如何知道有哪些消费者?哪些gatingSequense是从哪里来的?

在构建RingBuffer注册处理类的时候,就将消费者Sequense注册到RingBuffer中了。

看代码的话,定位到gatingSequences在AbastractSequencer,对应的有个addGatingSequenses方法用于注入gatingSequence

publicabstractclassAbstractSequencerimplementsSequencer{//...protectedvolatileSequence[]gatingSequences=newSequence[0];@OverridepublicfinalvoidaddGatingSequences(Sequence...gatingSequences){SequenceGroups.addSequences(this,SEQUENCE_UPDATER,this,gatingSequences);}//...}再查看addGatingSequences被调用的地方,即通过RingBuffer的方法,设置到Sequencer中,这个Sequencer是生产者使用的序号管理器

publicfinalclassRingBufferextendsRingBufferFieldsimplementsCursored,EventSequencer,EventSink{//...protectedfinalSequencersequencer;publicvoidaddGatingSequences(Sequence...gatingSequences){sequencer.addGatingSequences(gatingSequences);}//...}而RingBuffer的addGatingSequence则在Disruptor配置处理器的时候被调用

publicclassDisruptor{//...privatefinalRingBufferringBuffer;privatefinalConsumerRepositoryconsumerRepository=newConsumerRepository<>();publicEventHandlerGrouphandleEventsWith(finalEventProcessor...processors){for(finalEventProcessorprocessor:processors){consumerRepository.add(processor);}finalSequence[]sequences=newSequence[processors.length];for(inti=0;i(this,consumerRepository,Util.getSequencesFor(processors));}//...}缓存的意义是什么?

我们看到在SiingleProducerSequencer的next方法中,会缓存上一次的消费者最小序列号,这有什么用呢?

用途就是不需要每次都读取各消费者的序号,只要没超过上一次的最小值的地方都可以直接分配,如果超过了,则进行再次判断

为啥读取最小值不需要保证原子性?

看了这个获取最小消费序号的,可能会奇怪,为啥这个操作不需要上锁,这个不是会获取到旧值吗?

确实,这个最小值获取到的时候,实际上数值已经变更。但是由于我们的目的是为了防止指针越位,所以用旧值是没有问题的。(旧值<=实际上的最小值)

publicstaticlonggetMinimumSequence(finalSequence[]sequences,longminimum){for(inti=0,n=sequences.length;i

THE END
1.猫毛草的功效与作用是什么快速问医生病情分析:猫毛草有利尿通淋,清热止血,消炎杀菌的作用,一般经常用于治疗肾盂肾炎,尿路感染,肾结石,...https://m.120ask.com/askg/bd_detail/103729295
2.猫毛球制作只需要猫毛就能做的简单玩具铲屎官们都对自制猫玩具感兴趣,小编教大家做一个毛球玩具,只需要三步,将梳理下来的毛集中,搓成毛球,串上绳子就是一个猫玩具啦。 自制猫玩具第一步:给猫梳毛 小编教大家来做猫毛球玩具,材料只需要一把梳毛的数字、一根针、和猫身上的猫。 自制猫玩具第二步:搓毛球 ...https://mip.xiaokeai.com/cat/baike/16797.html
3.猫知识大全斯芬克斯猫(无毛猫),无毛猫最显著的特征是基本没有毛发覆盖在身体上,适合那些喜欢养猫,但不喜欢猫毛或者对猫毛过敏的人群,也是受欢迎的品种。 橘猫,橘猫是指毛色呈现橘色或橙色的猫咪,所有橘色的猫都可以称为橘猫,只和毛色有关,与品种无关,普遍存在于混种猫和不具独特规定毛色的猫品种。 https://www.360doc.cn/article/253213_1120556786.html
4.如何减少布偶猫掉毛布偶猫是长毛品种猫咪,布偶猫掉毛非常厉害,特别是在3-4个月大的时候布偶猫开始爆毛,平时一年四季掉毛都比较多,不过如果布偶猫身上的毛变少了,那铲屎官就需要考虑是不是猫咪补充的营养不够。接下来氧宠博士就将根据布偶猫掉毛严重怎么办这个问题,带大家了解一下减少布偶猫掉毛的方法。 https://www.isdpp.com/xq-196.html
5.“天热了,给猫剃个毛吧?”快住手!6月以来,武汉的气温一路攀升,越来越多宠友来咨询,天气这么热可以给猫剃毛吗? 在网上冲浪发现,给猫剃毛的还真不少,造型也是千奇百怪。 看到这些照片,真是一点都笑不出来。 对猫来说,为了降温而剃毛完全就是两脚兽的一厢情愿,不仅不能降温,对猫来说反而是一种伤害! https://weibo.com/ttarticle/p/show?id=2309404782839253304305
1.康巴地区民间对歌(一)只发现全是猫狗皮 你那个丝绸宝玉箱 打开的钥匙无需有 我配个钥匙打开了 但没有见到丝绸布 只发现全是猫狗毛 男: 有山歌是那莲生教 每一个教后还有教 有山歌是那六字真言 每一个字后还有字 女: 家养牛犊真狂妄 与我野牦牛斗角力 你不怕变成独角牛 ...https://zangdiyg.com/Home/Article/detail/id/7401.html
2.老鼠最怕什么东西猫毛 很多人对猫毛过敏,而老鼠也不喜欢这种东西。如果有朋友养猫,收集一些猫毛放在不想有老鼠的地方是不错的做法。 樟脑球 樟脑球能防止蛀虫接近毛衣,并能让你的衣柜充满像奶奶房间一样的气味。这种小东西的用途之一还包括驱逐老鼠和其它啮齿类动物。如果发现家里有老鼠,可以在它们出没过的小洞等地方放置樟脑球。https://www.jy135.com/shenghuo/102428.html
3.猫咪剃毛的好处和坏处爱宠网炎炎夏日,接近40度高温的酷暑我们人类都难以抵挡,更不用说猫咪这种天天穿着皮草的动物,因此有的铲屎官会因为担心猫咪中暑而剃掉它们的毛发。但你知道猫咪剃毛除了带来清爽还有什么好处吗?除了好处难道没有坏处吗?如果你也有所想法有所疑问,那就来看看这篇吧~ ...https://www.lovepet.cn/a/zaixianwenda/196164.html
4.3岁猫毛弄进阴道内有什么影响呢真实医生回答如果担心的话,可以去医院做个宫腔镜阴道镜检查。然后如果发现了毛发,可以顺便取出来。顺便看一下阴道有没有其他的异常。 患者 但是她现在经常说肚子痛 朱蕾蕾医生 你不是说有很长时间了吗? 患者 是的,刚养下来的才几天弄的 朱蕾蕾医生 如果是很长时间的话,个人觉得肚子疼并不一定是猫毛引起的。 https://m.chunyuyisheng.com/qa/wlXDGDt-M6BGsVC_zhLddw/
5.猫什么地方最容易起跳蚤这个地方最容易被忽视猫身上的跳蚤长什么样? 题主会看到猫毛中有像星星一样耀眼的小黑点,眨眼就消失在猫毛中。 怎么判断猫身上有没有跳蚤? 跳蚤在猫的皮肤上是爬的,爬行速度很快,大小跟黑芝麻差不多。 身上如果生了跳蚤,翻开毛,会看到细小的黑色点点,那是跳蚤的排泄物。 http://m.boqii.com/article/401209.html
6.布偶猫的丝质毛和棉质毛哪个更好?平时经常有家长问我布偶猫毛质问题,所以今天在这里系统的跟大家聊一下关于毛质的问题。 布偶猫发展到今天,他的毛质大概可以分为棉质毛和丝质毛, 可以通过肉眼和手感分辨出来。也有个别的猫是丝绵混合。 丝质毛: 传统型布偶猫的被毛,其实是丝质毛,而且几乎没有或只有非常少的棉质底毛,手感非常丝滑并且非常...https://www.douban.com/note/808129067/
7.饲养金吉拉猫的注意事项,饲养金吉拉猫的注意事项是什么金吉拉猫的肠胃非常弱,一不注意,它们就会呕吐拉稀,比如下面的行为,对“金吉拉猫”肠胃伤害很大,宠主别再做了。 长期喂牛奶 金吉拉猫的肠胃敏感,牛奶中的乳糖比较多,而猫体内缺少分解乳糖的酶,猫咪很难消化吸收,就会出现腹泻等情况。宠主别再给金吉拉猫喂牛奶了,可以给它们喝舒化奶、宠物牛奶、酸奶或者羊奶粉。 https://chagougou.com/29812.html