關於ConcurrentSkipListMap的幾點見解

  之前看了ConcurrentSkipListMap的源碼,未做總結,今天做個總結,關於ConcurrentSkipListMap其實網上有很多文章,博主今天就不通篇大論,挑些精簡的來說。

  首先跳錶中維護一層時,即值存在level1時的底層數據結構爲:

當添加第二個元素時,通過拋硬幣算法算出!=0時,這裏我們只考慮加了一層level,底層數據結構的演化爲:

 

 其實這張圖就如網上很多的跳錶結構圖一樣,畫的沒問題,但是其實不能完全提現ConcurrentSkipListMap底層完全的數據結構,在這些圖中其實還維護了一種node的關係,不受level或者index的影響,如圖所示:

  從大的方面講,跳錶是通過HeadIndex跟Index這種層級及索引關係查找數據,其實最底層還是通過層級及索引關係查找到對應的node,博主在看源碼時就產生了一個疑惑,爲什麼源碼中維護的HeadIndex的數據結構所維護的node關係在跳錶的數據結構圖中提現不出來,看了很久才終於明白。所以想完全瞭解跳錶的結構,並根據源碼分析,還是要結合着兩張圖:

  最後補充一點,官網原話爲:

Indexing uses skip list parameters that maintain good search
performance while using sparser-than-usual indices: The
hardwired parameters k=1, p=0.5 (see method doPut) mean
that about one-quarter of the nodes have indices. Of those that
do, half have one level, a quarter have two, and so on (see
Pugh's Skip List Cookbook, sec 3.4).  The expected total space
requirement for a map is slightly less than for the current
implementation of java.util.TreeMap.

 大概意思是:索引使用跳躍表參數來保持良好的搜索性能,同時使用比通常少的索引:硬連接參數k=1, p=0.5(參見方法doPut)意味着大約四分之一的節點有索引。其中,有一半的人只有一個level,四分之一的人有兩個level,以此類推。從這句話可以知道,並不是所有node節點都有Index與之對應:

  總結來說,就是兩個相鄰Index的node並不一定是直接相關聯的(nodePre.next != nodeAfter),中間可能存在多個node節點,只是這些node節點並未生成對應的Index。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章