【问题标题】:Pollable disruptor可轮询破坏者
【发布时间】:2019-01-12 08:09:49
【问题描述】:

我做了很多研究,但我还没有找到解决方案。我想找一个pollable ring buffer,类似于LMAX disruptor。我有很多出版商和一个读者。

disruptor 的问题在于它使用自己的专用线程(池)来读取消息,但我想从单独的线程中读取它们,它也可以做其他事情。

我看到的另一种选择是使用agrona 中的ManyToOneConcurrentArrayQueuejctools 中的MpscArrayQueue。但是这些队列preallocates 都不像LMAX disruptor 那样做对象。当我调用ManyToOneConcurrentArrayQueue::offerMpscArrayQueue::offer 时,我将对象的所有权转移到队列中,当我调用ManyToOneConcurrentArrayQueue::pollMpscArrayQueue::poll 时,我从它们那里获得所有权。这是一个问题,因为它迫使我有一个单独的对象池来回收这些对象以避免产生垃圾。这显然比拥有preallocated array 更慢,因为preallocated array 始终保持其内容的所有权(LMAX 中断程序包中的一个 la RingBuffer)。

我不想重新发明轮子并自己构建这样的数据结构,但我也找不到现有的。如果有人遇到过这样的结构,我将不胜感激。

【问题讨论】:

  • 您最终选择了什么解决方案?我有完全相同的用例(并且来到这里是因为这是 ManyToOneConcurrentArrayQueue 的唯一互联网热门 - 除了刚刚抓取 github 的 10k 个站点之外)。
  • 我决定避免脑部手术,所以我只使用 MpscArrayQueue 并回收对象。实际上,它不是最理想的,但异步分析器并没有将这个地方显示为热点。
  • 我也做了同样的事情 - 一个队列是 'queue' ,另一个队列将对象传递回生产者以供重用。两个队列长度相同,我们在启动时预填充重用队列。

标签: java concurrency low-latency disruptor-pattern


【解决方案1】:

disruptor 库包含一个 EventPoller

【讨论】:

  • 这应该是公认的答案。对于必须在特定线程上处理某些事件的 GUI 应用程序来说,这非常好。例如,在 JavaFX 应用程序中,您可以从每帧调用一次的 AnimationTimer 设置连续轮询。
  • 谢谢你的想法。我看到 EventPoller 根本没有任何文档。这是它的构造函数的外观。 public EventPoller(final DataProvider<T> dataProvider, final Sequencer sequencer, final Sequence sequence, final Sequence gatingSequence) 如何正确实例化它?我从哪里得到所有这些论点?如果使用中断器,则不需要手动操作这些类。您能否分享一小段创建正确 EventPoller 的代码?
  • @Vadim RingBuffer#newPoller 是您想要的,而不是构造函数。在源存储库的 src/examples 中有几个示例,“PullWithPoller”和“PullWithBatchedPoller”。确实,EventPoller 在当前版本中没有 javadoc。但是,master 分支中有文档。
【解决方案2】:

可以直接使用 LMAX 干扰器RingBuffer 实现。

可能在不启动整个破坏者的情况下利用项目的其他部分。

【讨论】:

  • 谢谢。我已经考虑过了。然而,RingBuffer 不足以让整个事情发挥作用。还需要 MultiProducerSequencer 的自定义可轮询实现,如果它已经可用,我想避免自己编写它。好像不是。
猜你喜欢
  • 1970-01-01
  • 2015-12-22
  • 2023-03-20
  • 2012-04-07
  • 2017-06-13
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
相关资源
最近更新 更多