[Java] ConcurrentMap 分析和思考__Java

來源:互聯網
上載者:User

預備知識:Java HashMap and HashSet 的實現機制

 

由預備知識可以知道hashmap 的儲存結構為:

   

(映像來自http://www.ibm.com/developerworks/cn/java/j-lo-hash/)

 

也是說:一個hashmap 內部含有一個Entity 類行的數組,這個數組中的元素都是Entity。實際上我們放入map 中的key 和 value 就對應一個Entity 對象,這個Entity 對象包含一個key、value、hashcode(key 的)和一個Entity 的引用,通過這個引用,Entity 可以形成一個鏈表。在圖中,藍色矩形方框代表數組,橙色橢圓代表Entity 對象。

 

注意HashMap 類不是安全執行緒的。

 

  ConcurrentMap  主要的子類是ConcurrentHashMap。

原理:一個ConcurrentHashMap 由多個segment 組成,每個segment 包含一個Entity 的數組。這裡比HashMap 多了一個segment 類。該類繼承了ReentrantLock 類,所以本身是一個鎖。當多線程對ConcurrentHashMap 操作時,不是完全鎖住map, 而是鎖住相應的segment 。這樣提高了並發效率。

 

建構函式的分析:

 

/** * Creates a new, empty map with a default initial capacity (16), * load factor (0.75) and concurrencyLevel (16). */ public ConcurrentHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); }

 

這是ConcurrentHashMap 的無參建構函式,可以看到預設大小為16,負載因子0.75,並發層級為16.

 

 

Put 函數的分析:

/** * Maps the specified key to the specified value in this table. * Neither the key nor the value can be null. * * <p> The value can be retrieved by calling the <tt>get</tt> method * with a key that is equal to the original key. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt> * @throws NullPointerException if the specified key or value is null */ public V put(K key, V value) { if (value == null) throw new NullPointerException(); int hash = hash(key.hashCode()); return segmentFor(hash).put(key, hash, value, false); }

 

可以看出通過hash() 函數得到key 的雜湊值,在得到相應的segment,在通過segment 儲存Entity。

 

同時為了避免“檢測再修改”(有條件安全執行緒參見[2])等並發問題,ConcurrentHashMap 提供了putIfAbsent(K key, V value)  方法,當key 不存在時,添加。(key 的存在靠兩個條件,一個是key的hashcode方法,另外一個是key 的equal 方法)

 

 

優點:由於對對應segment  加鎖,而不是鎖定整個map,並發性得到了提高。能夠直接提高插入、檢索以及移除操作的延展性。

缺點:當遍曆map 中的元素時,需要擷取所有的segment 的鎖,使用遍曆時慢。鎖的增多,佔用了系統的資源。使得對整個集合進行操作的一些方法(例如 size() 或 isEmpty() )的實現更加困難,因為這些方法要求一次獲得許多的鎖,並且還存在返回不正確的結果的風險。

 

參考資料:

1 通過分析 JDK 原始碼研究 Hash 儲存機制

2 Java 理論與實踐: 並發集合類

3 Java 理論與實踐: 構建一個更好的 HashMap

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.