對多線程寫入的RingBuffer的影響是輕微的,但是在非常重的負載下可能是顯着的。
RingBuffer實現包含一個next
節點,其中將進行下一個添加。如果只有一個線程正在向環寫入,則該過程總是在最短時間內完成,即buffer[head++] = newData
。
要處理多線程,同時避免鎖定,你通常會做類似while (!buffer[head++].compareAndSet(null,newValue)){}
。這個緊密的循環將繼續執行,而其他線程正在干擾數據的存儲,從而減慢城鎮吞吐量。
請注意,我已經使用了上面的僞代碼,在我的實現here中看看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;
}
// ...
}
因此,對於N個生產者(其中n不是很大)使用它會比在寫入訪問上阻塞更快嗎? – vach
@vach - 是的。任何非阻塞算法都優於使用鎖的算法。 – OldCurmudgeon
我不明白的是LMAX如何在單線程中做到這一點?他們同時得到很多訂單,他們如何讓他們在單線程中獲得鈴聲? 任何想法:)? – vach