多线程写入对 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;
}
// ...
}