我已经了解了 LMAX 和这个叫做 RingBuffer 的美妙概念。 所以人们告诉我们,当只用一个线程写入环形缓冲区时,性能比多个生产者要好得多......
但是我真的不觉得典型的应用程序可以只使用一个线程在环形缓冲区上写...我真的不明白 lmax 是怎么做到的(如果他们这样做的话)。例如N个不同的交易员在交易所下订单,这些都是异步请求转换为订单并放入ringbuffer,他们怎么可能用一个线程来写?
问题 1. 我可能遗漏了某些东西或误解了某些方面,但是如果您有 N 个并发生产者,如何将它们合并为 1 个而不相互锁定?
问题 2。我记得 rxJava observables,你可以使用 Observable.merge 将 N 个 observables 合并为 1 个我想知道它是否以任何方式阻止或维护任何锁?
最佳答案
多线程写入对 RingBuffer 的影响很小,但在非常重的负载下可能会很重要。
RingBuffer 实现包含一个 next
节点,下一次添加将在该节点进行。如果只有一个线程正在写入环,该过程将始终在最短时间内完成,即 buffer[head++] = newData
。
要在避免锁定的同时处理多线程,您通常会执行类似 while ( !buffer[head++].compareAndSet(null,newValue)){}
的操作。当其他线程干扰数据存储时,这个紧密循环将继续执行,从而降低吞吐量。
请注意,我在上面使用了伪代码,看看我的实现中的getFree
here一个真实的例子。
// Find the next free element and mark it not free.
private Node<T> getFree() {
Node<T> freeNode = head.get();
int skipped = 0;
// Stop when we hit the end of the list
// ... or we successfully transit a node from free to not-free.
// This is the loop that could cause delays under hight thread activity.
while (skipped < capacity && !freeNode.free.compareAndSet(true, false)) {
skipped += 1;
freeNode = freeNode.next;
}
// ...
}
关于java - 用单线程写 LMAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30237952/