乙個可無限伸縮且無ABA問題的無鎖佇列

2021-09-06 11:07:06 字數 1014 閱讀 2406

關於無鎖佇列,詳細的介紹請參考陳碩先生的《無鎖佇列的實現》一文。然進一步,如何實現乙個不限node數目即能夠無限伸縮的無鎖佇列,即是本文的要旨。

無鎖佇列有兩種實現形式,分別是陣列與鍊錶。以陣列實現的無鎖佇列,限定了基本node的數目,然沒有aba問題。以鍊錶實現的無鎖佇列,在記憶體允許的情況下可以新增任意數目的node,然有aba問題。如何取二者的優點而摒棄其各自的缺點呢?

如果要做到可以無限伸縮,那麼這種無鎖佇列須採用鍊錶實現,然如何解決aba問題呢?

aba問題的本質就是位址重用,即兩個(或多個)訪問者訪問乙個node,其中乙個釋放了這個node,此時os會**這個node。然後另外乙個訪問者要新生成乙個node時,os會把剛釋放掉的那個node的記憶體空間分配給這個訪問者。在這個過程中,如果我們不把釋放掉的node還給os,是不是問題就解決了?

可儲存需要釋放的node而不還給os的技術,我能想到的是記憶體池。乙個以鍊錶形式實現的無鎖佇列使用它的記憶體池時,如果要對這個記憶體池加鎖,那就不是無鎖佇列了。

這個記憶體池中每個node大小一致,用乙個陣列形式的無鎖佇列實現即可。本文需要的無鎖佇列便是用列表實現的,而且基於陣列無鎖佇列記憶體池。

這裡面還有乙個問題。還是上面的那個場景,node被訪問者釋放後,此時由記憶體池儲存著,然後另乙個訪問者要申請乙個node的記憶體空間,便會向記憶體池申請,如果記憶體池是把那個剛被釋放掉的node空間分配給它呢?相當於記憶體池替代了os,問題依然沒有解決。

既然記憶體空間現在由記憶體池而非os管理著,哪我們就可以想辦法解決了。

還是上面那個場景,如果記憶體池中有很多個node,佇列形式的記憶體池還會把剛被釋放掉的node空間分配出去嗎?所以需要在記憶體池中儲存多個node。但儲存多少合適呢?儲存的node數量大於等於同時向記憶體池申請node空間的訪問者即可。

node的數量取決於訪問者的數目,若訪問者是執行緒,則這個數目就是就是寫執行緒的數目,這個引數可以讓使用者設定。為了程式設計方便,我假設執行緒池執行緒寫執行緒最多不會超過2048個,這個值應該大於當前多數伺服器中cpu數量。

歡迎批評指正。

此記。

乙個可無限伸縮且無ABA問題的無鎖佇列

關於無鎖佇列,詳細的介紹請參考陳碩先生的 無鎖佇列的實現 一文。然進一步,如何實現乙個不限node數目即能夠無限伸縮的無鎖佇列,即是本文的要旨。無鎖佇列有兩種實現形式,分別是陣列與鍊錶。以陣列實現的無鎖佇列,限定了基本node的數目,然沒有aba問題。以鍊錶實現的無鎖佇列,在記憶體允許的情況下可以新...

乙個可無限伸縮且無ABA問題的無鎖佇列

關於無鎖佇列,詳細的介紹請參考陳碩先生的 無鎖佇列的實現 一文。然進一步,如何實現乙個不限node數目即能夠無限伸縮的無鎖佇列,即是本文的要旨。無鎖佇列有兩種實現形式,分別是陣列與鍊錶。以陣列實現的無鎖佇列,限定了基本node的數目,然沒有aba問題。以鍊錶實現的無鎖佇列,在記憶體允許的情況下可以新...

學習如何構建乙個高效且可伸縮的快取

我們平時處理高併發的請求處理時,伺服器的壓力會很大。我們常做的就是構建乙個高效的可伸縮的快取來減輕伺服器的壓力。1.第一次嘗試 分析 使用 hashmap充當cache。public inte ce computable public class memoizer1implements comput...