Disruptor底层组件解析
RingBuffer密切相关的两个对象:SequenceBarrier和Sequencer。
SequenceBarrier原理精讲
sequenceBarrier是消费者与RingBuffer之间的桥梁。在Disruptor中,消费者直接访问的是SequenceBarrier,而不是RingBuffer,因此SequenceBarrier能减少RingBuffer上的并发冲突。
假设某一时刻的场景:(1)消费者正在消费第6条数据。(2)消费者此刻能够检测到RingBuffer中最大的下标是10.
此时消费者就会通过SequenceBarrier提供的waitFor()方法进入阻塞状态,给予生产者一定的时间去生产数据。waitFor()的参数是消费者下一个即将读取的数据7,返回值就是此刻可检测的最大下标10.与此同时,生产者会持续向RingBuffer中增加数据,当增加到第10条数据时,就会唤醒消费者结束waitFor()方法,消费者结束阻塞后就会消费第7/8/9/10号数据。
这样一来,当消费者的消费速度大于生产者的生产速度时,消费者就可以通过waitFor()方法给予生产者一定的缓冲数据,从而协调了生产者和消费者的速度问题。
Sequencer核心概念
Sequencer形式上是一个接口,并且有SingleProducerSequencer和MultiProducerSequence两个实现类,分别代表单生产者与多生产者。
Sequencer是生产者与缓冲区RingBuffer之前的桥梁。生产者可以通过Sequencer向RingBuffer申请数据的存放空间,并使用publish()方法通过WaiteStrategy通知消费者。WaitStrategy是当消费者没有数据可以消费时的等待策略,常见有几种。
BusySpinWaitStrategy:自旋等待。能够及时发现新生产出来的数据,但对CPU资源的占用较多。
BlockingWaitStrategy:使用了Lock接口的加锁机制,延迟较大,但对CPU资源的占用较少。
SleepWaitStrategy:在多次循环尝试不成功后,主动让出CPU,等待下次调度。
如果多次调度后仍不成功,就会先休眠一段时间后再尝试。不难发现,此策略是对BusySpinWaitStrategy和BlockingWaitStrategy策略的一种折中。
YieldingWaitStrategy:在多次循环尝试不成功后,主动让出CPU,等待下次调度。
PhaseBackoffWaitStrategy:先自旋等待(默认自旋10000次),如果仍然没有新数据产生再主动让出CPU,之后再使用备用的WaitStrategy重新等待。