本文主要是介绍disruptor(2)-等待策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在生产者消费者模式中,等待策略对消费者而言,是一个获取消息感知的方式,可以用轮询,事件触发来实现。
对于生产者而言,等待策略表现在队列池已满的情况,如何等待消息被消费,在一般不重要的场景中,我们可能是就直接抛弃了。
如我们自己使用queue作为等待队列,我们消费时一般用poll()这么去等待数据到来,如果直接用while循环,那cpu会消耗的很严重。这时我们常见的解决办法是在while循环中加上Thread.sleep(xxx),当没有消耗到数据时,则等待一小段时间再重试。
当然也可以直接使用BlockingQueue,使用take阻塞方法。
下面我们来看下Disruptor的等待策略实现:
在disrutpor中,WaitStrategy接口定义了waitFor和signalAllWhenBlocking两个方法。对应阻塞等待和唤醒,在这里我们重点关注几个常用的waitFor方法的实现。
- BlockingWaitStrategy
采用ReentrantLock和Condition实现,由于有锁实现,性能相对而言并不好。
这里作者采用比较巧妙的方法,只在cursorSequence<sequence时,使用processorNotifyCondition.await,在后续消费者层级依赖判断上使用了ThreadHints.onSpinWait的自旋实现。 - YieldingWaitStrategy
这个策略由于使用yield,会占用100%cpu,但会比onSpinWait更容易让出cpu资源。
实现上,作者先将100循环减到0,如果在这个过程中仍然需要等待,则使用采用Thread.yield等待。 - SleepingWaitStrategy
允许配置retries和sleepTimeNs, 是性能和CPU资源的一个很好的折中方案。
也是先对counter进行减一操作,当小于100时,则边减一边yield。当counter到达0时,则使用LockSupport.parkNanos(sleepTimeNs)。
这篇关于disruptor(2)-等待策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!