我已经向大家介绍了LMAX和这个叫做RingBuffer的奇妙概念。所以男人们告诉我们,当只写一个线程时,要比用多个生产者写要好得多.
然而,我并不认为tipical应用程序可能只使用一个线程在循环缓冲区上写.我真的不明白lmax是怎么做到的(如果他们这么做的话)。例如,N个不同的交易者在交易所下订单,这些都是异步的请求,被转换成订单并放入了循环缓冲区,他们怎么能写那些使用一个线程呢?
问题1.我可能遗漏了一些东西或者误解了一些方面,但是如果你有N个并发的生产者,怎么可能把它们合并成1而不彼此锁定呢?
问题2 :我记得rxJava可观测值,您可以使用Observable.merge将N个可观测值合并为1--我想知道它是否以任何方式阻塞或维护了任何锁?
发布于 2015-05-14 13:28:27
多步书写对RingBuffer的影响很小,但在非常重的负载下可能会很大。
RingBuffer实现保存一个next节点,在该节点中将进行下一次添加。如果只有一个线程正在写入环,进程将始终在最短的时间内完成,即buffer[head++] = newData。
要在避免锁定的同时处理多线程,通常需要执行类似于while ( !buffer[head++].compareAndSet(null,newValue)){}的操作。当其他线程干扰数据存储时,这个紧循环将继续执行,从而降低吞吐量。
请注意,我使用了上面的伪代码,在我的实现getFree中查看一下这里中的一个实际示例。
// 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;
}
// ...
}发布于 2015-05-14 14:09:25
在内部,RxJava的合并使用了一个序列化构造,我称之为发射极回路,它使用synchronized并正在阻塞。
我们的“客户端”主要在吞吐量和延迟、不敏感的情况或完全单线程和阻塞的情况下使用合并,这并不是真正的问题。
可以编写一个我称为排排的非阻塞序列化程序,但是合并不能配置为使用它。
如果您愿意手动处理生产者线程和消费者线程,您还可以直接查看JCTools的MpscArrayQueue。
https://stackoverflow.com/questions/30237952
复制相似问题