千家信息网

Disruptor的原理是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"Disruptor的原理是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Disruptor的原理是什么"吧!Disruptor
千家信息网最后更新 2026年11月01日Disruptor的原理是什么

这篇文章主要讲解了"Disruptor的原理是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Disruptor的原理是什么"吧!

Disruptor通过以下设计来解决队列速度慢的问题:

  • 环形数组结构

  • 为了避免垃圾回收,采用数组而非链表。同时,数组对处理器的缓存机制更加友好。

  • 元素位置定位,数组长度2^n,通过位运算,加快定位的速度。下标采取递增的形式。不用担心index溢出的问题。index是long类型,即使100万QPS的处理速度,也需要30万年才能用完。 - 无锁设计

  • 每个生产者或者消费者线程,会先申请可以操作的元素在数组中的位置,申请到之后,直接在该位置写入或者读取数据。

下面忽略数组的环形结构,介绍一下如何实现无锁设计。整个过程通过原子变量CAS,保证操作的线程安全。

一个生产者

写数据

生产者单线程写数据的流程比较简单: 1. 申请写入m个元素; 2. 若是有m个元素可以写入,则返回最大的序列号。这儿主要判断是否会覆盖未读的元素; 3. 若是返回的正确,则生产者开始写入元素。

多个生产者

多个生产者的情况下,会遇到"如何防止多个线程重复写同一个元素"的问题。Disruptor的解决方法是,每个线程获取不同的一段数组空间进行操作。这个通过CAS很容易达到。只需要在分配元素的时候,通过CAS判断一下这段空间是否已经分配出去即可。

但是会遇到一个新问题:如何防止读取的时候,读到还未写的元素。Disruptor在多个生产者的情况下,引入了一个与Ring Buffer大小相同的buffer:available Buffer。当某个位置写入成功的时候,便把availble Buffer相应的位置置位,标记为写入成功。读取的时候,会遍历available Buffer,来判断元素是否已经就绪。

下面分读数据和写数据两种情况介绍。

读数据

生产者多线程写入的情况会复杂很多: 1. 申请读取到序号n; 2. 若writer cursor >= n,这时仍然无法确定连续可读的最大下标。从reader cursor开始读取available Buffer,一直查到第一个不可用的元素,然后返回最大连续可读元素的位置; 3. 消费者读取元素。

如下图所示,读线程读到下标为2的元素,三个线程Writer1/Writer2/Writer3正在向RingBuffer相应位置写数据,写线程被分配到的最大元素下标是11。

读线程申请读取到下标从3到11的元素,判断writer cursor>=11。然后开始读取availableBuffer,从3开始,往后读取,发现下标为7的元素没有生产成功,于是WaitFor(11)返回6。

然后,消费者读取下标从3到6共计4个元素。

写数据

多个生产者写入的时候: 1. 申请写入m个元素; 2. 若是有m个元素可以写入,则返回最大的序列号。每个生产者会被分配一段独享的空间; 3. 生产者写入元素,写入元素的同时设置available Buffer里面相应的位置,以标记自己哪些位置是已经写入成功的。

如下图所示,Writer1和Writer2两个线程写入数组,都申请可写的数组空间。Writer1被分配了下标3到下表5的空间,Writer2被分配了下标6到下标9的空间。

Writer1写入下标3位置的元素,同时把available Buffer相应位置置位,标记已经写入成功,往后移一位,开始写下标4位置的元素。Writer2同样的方式。最终都写入完成。

防止不同生产者对同一段空间写入的代码,如下所示:

public long tryNext(int n) throws InsufficientCapacityException{    if (n < 1)    {        throw new IllegalArgumentException("n must be > 0");    }     long current;    long next;     do    {        current = cursor.get();        next = current + n;         if (!hasAvailableCapacity(gatingSequences, n, current))        {            throw InsufficientCapacityException.INSTANCE;        }    }    while (!cursor.compareAndSet(current, next));     return next;}

通过do/while循环的条件cursor.compareAndSet(current, next),来判断每次申请的空间是否已经被其他生产者占据。假如已经被占据,该函数会返回失败,While循环重新执行,申请写入空间。

消费者的流程与生产者非常类似,这儿就不多描述了。

总结

Disruptor通过精巧的无锁设计实现了在高并发情形下的高性能。

感谢各位的阅读,以上就是"Disruptor的原理是什么"的内容了,经过本文的学习后,相信大家对Disruptor的原理是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

元素 生产 生产者 位置 下标 线程 数组 空间 数据 分配 最大 成功 多个 情况 时候 问题 原理 消费者 消费 设计 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡 博彦科技互联网金融 广州紫鲸互联网科技有限公司 互联网最新的科技 互联网 的科技创新 美国互联网黑科技 互联网科技logo 互联网养老 桔豆科技 科技赋能互联网健康 崇明区互联网教育科技诚信经营 苏州五指互联网络科技有限 互联网保险科技创业 民营互联网公司国防科技 佛山市翊博互联网络科技有限公司 区块链结合互联网科技 工业互联网展湾科技股份有限公司 工业互联网山东科技大学 上海钢联属于互联网科技股吗 广州富喜互联网络科技 广州有谷有贝互联网科技有限公司 科技平台互联网 科技互联网创业计划书 富国互联网科技创新基金 顶级互联网科技成果有哪些 深圳市罗太互联网科技有限公司 爱医互联网络科技 黑科技 体验场景 互联网大会 南通创西澳互联网科技有限公司 广东鹅鹅鹅互联网科技有限公司 武汉亿视互联网科技有限公司
0