Disruptor 本质是一个内存队列,内存队列的一个很大的问题在于宕机无法回复,即它存在易失性。
特点
可以拿它跟JDK提供的原生队列进行对比
- 无锁
- 采用环形数组
- 缓存行填充
分析
说它完全无锁,其实非也,通过数组构造的环形数组,由于它本身是一个基于生产者-消费者模型,所以会存在生产->消费的过程,为了防止不要过度消费或者过度生产,提供了各种‘锁’策略。
-
无锁,是指通过CAS的方式来保证数据的更新时的一致性问题。
-
数组的优势在于内存固定,相比较链表而言对GC更友好,不会产生大量的内存碎片问题,而且在内存读取方面也有缓存行加载的优势(优势也可能是劣势)。
-
缓存行填充,指的是在并发情况下不同的线程同时访问同一个缓存行导致的并发冲突,虽然各自访问不同的数据,通过缓存行填充来移除这样的并发冲突导致。(缓存一致性协议MESI)
缓存行的问题,就是著名的伪共享的问题
源码
源码也不是很复杂,主要关注如下几个核心类
- RingBuffer
- Sequence
- SingleProducerSequencer 、 MultiProducerSequencer
- BatchEventProcessor | WorkProcessor 、WorkerPool
- WaitStrategy
学习的主要目的是跟原生的JDK队列进行对比,目前绝大多数的主流高性能框架都优先选择
Disruptor
,所以了解其原理上的优势与劣势,以便让自己在使用的时候有更好的选择
队列 | 有界性 | 锁 | 数据结构 |
---|---|---|---|
RingBuffer | 有界 | 无锁 | 数组 |
ArrayBlockingQueue | 有界 | 锁 | 数组 |
LinkedBlockingQueue | 有界/无界 | 锁 | 链表 |
ConcurrentLinkedQueue | 无界 | 无锁 | 链表 |
LinkedTransferQueue | 无界 | 无锁 | 链表 |
PriorityBlockingQueue | 无界 | 无锁 | 堆 |

网友评论