为了账号安全,请及时绑定邮箱和手机立即绑定

并发编程框架Disruptor实战 - 核心类RingBuffer

标签:
Java

5be0415b0001c9ac10000124.jpg


squencer 可简单理解为序号
waitStrategy 是一种策略等待


5be0415b000124f810000117.jpg

LMAX Disruptor,LMAX是一个新型的交易平台,号称能够单线程每秒处理数百万的订单
对高性能编程领域的一些传统观点,有点不对劲。这是一种更好、更快地在线程间共享数据的方法

从这个站点,你可以下载到一篇解释什么是Disruptor及它为什么如此高性能的文档

首先介绍ringbuffer。我对Disruptor的最初印象就是ringbuffer。但是后来我意识到尽管ringbuffer是整个模式(Disruptor)的核心,但是Disruptor对ringbuffer的访问控制策略才是真正的关键点所在。

1  是什么?

5be0415b0001192610000414.jpg

正如名字所说的一样,它是一个环(首尾相接的环),可用做在不同线程间传递数据的buffer


5be0415c0001b5a205000484.jpg

RingBuffer

RingBuffer拥有一个序号,这个序号指向数组中下一个可用的元素


5be0415d0001850c10000029.jpg


5be0415d0001a41e10000169.jpg


5be0415e0001c12510000518.jpg

数组结构

如下图图片表示序号,这个序号指向数组的索引4的位置

5be0415e0001b66602180178.jpg

RingBufferInitial


随着不停地填充该buffer(可能也会有相应的读取),这个序号会一直增长,直到绕过这个环

5be0415e00017a0102180178.jpg


要找到数组中当前序号指向的元素,可以通过mod操作


sequence mod array length = array index

以上面的RingBuffer为例(Java的mod语法):12 % 10 = 2 简单吧!

上图中的RingBuffer只有10个槽完全是个意外
如果槽的个数是2的N次方更有利于基于二进制的计算机进行计算

2的N次方换成二进制就是1000,100,10,1这样的数字
sequence & (array length-1) = array index
比如一共有8槽,3 &(8 -1)= 3,HashMap就是用这个方式来定位数组元素的,这种方式比取模的速度更快

2 什么用呢

如果你看了维基百科里面的关于环形buffer的词条,RingBuffer实现方式,与其最大的区别在于:没有尾指针

只维护了一个指向下一个可用位置的序号
选择用环形buffer的最初原因就是想要提供可靠的消息传递,需要将已经被服务发送过的消息保存起来,这样当另外一个服务通过nak (拒绝应答信号)告诉我们没有成功收到消息时,我们能够重新发送给他们

咋看,环形buffer非常适合这个场景。它维护了一个指向尾部的序号,当收到nak(校对注:拒绝应答信号)请求,可以重发从那一点到当前序号之间的所有消息:

5be0415e00012dbc03200149.jpg

RingBufferReplay.png


ring buffer和常用的队列之间的区别是,不删除buffer中的数据,也就是说这些数据一直存放在buffer中,直到新的数据覆盖他们
这就是和维基百科版本相比,不需要尾指针的原因
ringbuffer本身并不控制是否需要重叠,决定是否重叠是生产者-消费者行为模式的一部分

3 真的秀!

ringbuffer采用这种数据结构,是因为它在可靠消息传递方面有很好的性能
这就够了,不过它还有一些其他的优点。

  • 它是数组,所以要比链表快,而且有一个容易预测的访问模式
    这是对CPU缓存友好的,也就是说,在硬件级别,数组中的元素是会被预加载的,因此在ringbuffer当中,cpu无需时不时去主存加载数组中的下一个元素
    因为只要一个元素被加载到缓存行,其他相邻的几个元素也会被加载进同一个缓存行

  • 可以为数组预先分配内存,使得数组对象一直存在(除非程序终止)
    意味着不需要花大量的时间用于GC,此外,不像链表那样,需要为每一个添加到其上面的对象创造节点对象—对应的,当删除节点时,需要执行相应的内存清理操作



作者:JavaEdge
链接:https://www.jianshu.com/p/9a4076dd797f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消