返回

常见应用(四)Disruptor 内存消息队列

Disruptor 内存消息队列

Disruptor 内存消息队列是线程之间用于消息传递的队列

消息队列的实现

  1. “生产者 - 消费者模型”,需要先进先出,选择队列作为底层的数据结构

    • 基于链表实现的无界队列
      • 优点,快速动态扩容
      • 缺点,占用内存多
    • 基于数组实现的有界队列循环队列
      • 优点,限制队列的大小,限制内存的持续增长,防止 Out of Memory 错误
      • 缺点,搬移数据时性能变差,使用循环队列解决此问题
    • 选用顺序队列中的循环队列
  2. 加锁的“生产者 - 消费者模型”

    • 普通的“生产者 - 消费者模型”会出现的问题
      • 多个生产者并发地往队列中写入数据,可能会出现互相覆盖的情况
      • 多个消费者并发地从队列中消费数据,可能会出现重复读取的情况
    • 解决上述问题
      • 加锁,同一时间只允许一个线程执行,将并行改为串行
      • 串行会导致多个生产者同一时间生产数据时,效率的下降,可以使用 CAS(Compare And Swap)优化
  3. 无锁的“生产者 - 消费者模型”,Disruptor 使用的方式

    • 生产者生产数据

      • 在队列中添加数据前,申请可用空闲存储空间,批量地申请连续的 n 个(n >= 1)存储单元
      • 申请到 n 个存储单元之后,后续往队列中添加元素时,就可以不用加锁了

      申请存储单元的过程是需要加锁的

    • 消费者消费数据

      • 申请一批连续可读的 n 个存储单元
      • 申请到 n 个存储单元之后,后续的读取操作就可以不用加锁了

      申请连续可读的存储单元是需要加锁的

    • 当多个生产者申请了多块连续的存储单元时,若前一个存储单元没有完全写入数据,在这个存储单元的后续存储单元,无法被消费者读取

      disruptor
      disruptor

  4. 源码地址: https://github.com/LMAX-Exchange/disruptor

© Licensed Under CC BY-NC-SA 4.0