【发布时间】:2019-01-12 08:09:49
【问题描述】:
我做了很多研究,但我还没有找到解决方案。我想找一个pollable ring buffer,类似于LMAX disruptor。我有很多出版商和一个读者。
disruptor 的问题在于它使用自己的专用线程(池)来读取消息,但我想从单独的线程中读取它们,它也可以做其他事情。
我看到的另一种选择是使用agrona 中的ManyToOneConcurrentArrayQueue 或jctools 中的MpscArrayQueue。但是这些队列preallocates 都不像LMAX disruptor 那样做对象。当我调用ManyToOneConcurrentArrayQueue::offer 或MpscArrayQueue::offer 时,我将对象的所有权转移到队列中,当我调用ManyToOneConcurrentArrayQueue::poll 或MpscArrayQueue::poll 时,我从它们那里获得所有权。这是一个问题,因为它迫使我有一个单独的对象池来回收这些对象以避免产生垃圾。这显然比拥有preallocated array 更慢,因为preallocated array 始终保持其内容的所有权(LMAX 中断程序包中的一个 la RingBuffer)。
我不想重新发明轮子并自己构建这样的数据结构,但我也找不到现有的。如果有人遇到过这样的结构,我将不胜感激。
【问题讨论】:
-
您最终选择了什么解决方案?我有完全相同的用例(并且来到这里是因为这是 ManyToOneConcurrentArrayQueue 的唯一互联网热门 - 除了刚刚抓取 github 的 10k 个站点之外)。
-
我决定避免脑部手术,所以我只使用 MpscArrayQueue 并回收对象。实际上,它不是最理想的,但异步分析器并没有将这个地方显示为热点。
-
我也做了同样的事情 - 一个队列是 'queue' ,另一个队列将对象传递回生产者以供重用。两个队列长度相同,我们在启动时预填充重用队列。
标签: java concurrency low-latency disruptor-pattern