jdk1.8 ConcurrentHashMap 的工做原理及代碼實現,如何統計全部的元素個數

ConcurrentHashMap 的工做原理及代碼實現:java

相比於1.7版本,它作了兩個改進數組

一、取消了segment分段設計,直接使用Node數組來保存數據,而且採用Node數組元素做爲鎖來實現每一行數據進行加鎖來進一步減小併發衝突的機率安全

二、將本來數組+單向鏈表的數據結構變動爲了數組+單向鏈表+紅黑樹的結構。爲何要引入紅黑樹呢?在正常狀況下,key hash以後若是可以很均勻的分散在數組中,那麼table數組中的每一個隊列的長度主要爲0或者1.可是實際狀況下,仍是會存在一些隊列長度過長的狀況。若是還採用單向列表方式,那麼查詢某個節點的時間複雜度就變爲O(n); 所以對於隊列長度超過8的列表,JDK1.8採用了紅黑樹的結構,那麼查詢的時間複雜度就會下降到O(logN),能夠提高查找的性能; 數據結構

JDK1.8中,Segment類只有在序列化和反序列化時纔會被用到;併發

拋棄了原有的 Segment 分段鎖,而採用了 CAS + synchronized 來保證併發安全性。性能

  1. transient volatile Node<K,V>[] table;

 

static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        volatile V val;
        volatile Node<K,V> next;

        Node(int hash, K key, V val, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.val = val;
            this.next = next;
        }
}

1. Node類this

Node類主要用於存儲具體鍵值對,其子類有ForwardingNode、ReservationNode、TreeNode和TreeBin四個子類。四個子類具體的代碼在以後的具體例子中進行分析講解。spa

2. Traverser類設計

Traverser類主要用於遍歷操做,其子類有BaseIterator、KeySpliterator、ValueSpliterator、EntrySpliterator四個類,BaseIterator用於遍歷操做。KeySplitertor、ValueSpliterator、EntrySpliterator則用於鍵、值、鍵值對的劃分。code

3. CollectionView類

CollectionView抽象類主要定義了視圖操做,其子類KeySetView、ValueSetView、EntrySetView分別表示鍵視圖、值視圖、鍵值對視圖。對視圖都可以進行操做。

4. Segment類

Segment類在JDK1.8中與以前的版本的JDK做用存在很大的差異,JDK1.8下,其在普通的ConcurrentHashMap操做中已經沒有失效,其在序列化與反序列化的時候會發揮做用。

5. CounterCell

CounterCell類主要用於對baseCount的計數。

如何統計全部的元素個數:

transient volatile CounterCell[] counterCells; 可方便的計算hashmap中全部元素的個數,性能大大優於jdk1.7中的size()方法

相關文章
相關標籤/搜索