HashMap ConcurrentHashMap

問題描述

翻翻別人的面試經歷

這裏在知乎上看到的,分享出了本身面試阿里Java崗的面試題。html

clipboard.png

看了一下,除了Spring以外的其餘不少題都不會,可是不能拿學校沒講Java做爲藉口,由於可能講了也不會。面試

可是第九個問題,我以爲應該馬上話時間研究研究了,由於以前在緩存中用到了這個。數據庫

當時也不明白具體HashMapConcurrentHashMap究竟有什麼區別。數組

clipboard.png

只是記得以前看過有關大數據的場景下利用緩存減輕數據庫壓力的文章,文中說經常使用ConcurrentHashMap,因此這裏緩存就用這個了,其實並不懂原理,下面,讓咱們一塊兒來研究一下。緩存

Map

Map你們都熟悉了,Java中也有,JavaScript中也有。安全

Map是一種鍵值對類型的數據結構,根據鍵映射到值。數據結構

不分析源碼了,就把思想給你們講一下,如下主要以圖爲主。多線程

HashMap

Java7

clipboard.png

HashMap的本質是一個可變長度的數組,在數組中每一個位置保存的是一個Entry節點,該節點存儲有hashkeyvaluenext等信息。併發

Java7中的HashMap實現與咱們在數據結構中學習的相似,對key進行hash,若是衝突了,則添加到鏈表中。性能

而後查詢的時候就先根據hash找到相應的位置,而後根據鏈表逐一比較,返回相應的value。時間複雜度取決於鏈表的長度,時間複雜度爲O(N)

Java8

clipboard.png

Java8中對HashMap進行了優化,若是鏈表中元素超過8個時,就將鏈表轉化爲紅黑樹,以減小查詢的複雜度,將時間複雜度下降爲O(logN)

HashMap沒有對多線程的場景下作任何的處理,不用說別的,就兩個線程同時put,而後衝突了,二者須要操做一個鏈表/紅黑樹,這確定就會有錯誤發生,因此HashMap是線程不安全的。

HashTable

HashTableJava7中的HashMap相似,也是一個數組加鏈表,不過這個線程安全。

HashTable線程安全,可是它的線程安全是依賴將全部修改HashTable的代碼塊都用synchronized修飾。

synchronized關鍵字咱們以前在單例模式中用到過,它修飾的代碼塊,同一時刻只容許一個線程訪問,其餘線程會被阻塞,等待該線程執行完再執行。

因此,在HashTable中,一個線程在put,其他的線程在get的時候就會被阻塞,沒法並行。因此不推薦使用HashTable,雖然它線程安全。

ConcurrentHashMap

HashMap線程不安全,HashTable性能又很差,固然須要設計一個新類去解決這些問題,這就是ConcurrentHashMap

Java7

clipboard.png

這是Java7中實現線程安全的思路,ConcurrentHashMap16segment組成,每一個segment就至關於一個HashMap(數組+鏈表)。

segment最多16個,想要擴容,就是擴充每一個segment中數組的長度。

而後只要實現每一個segment是線程安全的,就讓這個Map線程安全了。每一個segment是加鎖的,對修改segment的操做加鎖,不影響其餘segment的使用,因此理想狀況下,最多支持16個線程併發修改segment,這16個線程分別訪問不一樣的segment

同時,在segment加鎖時,全部讀線程是不會受到阻塞的。

這樣設計,putget的基本操做就是先找segment,再找segment中的數組位置,再查鏈表。

Java8

後來人們發現Java7這樣設計太複雜了,迴歸本質。

HashMap線程不安全的問題徹底都是出在對鏈表/紅黑樹的操做上,爲何非要建一個segment加鎖呢?直接對鏈表/紅黑樹加鎖不就行了?

clipboard.png

因此Java8ConcurrentHashMap徹底就是HashMap進行加鎖,實現線程安全。

這裏總結的很簡單,其實源碼中對這個的實現特別複雜,有興趣的能夠去看看,反正我是看着頭大。

總結

  1. HashMap線程不安全。
  2. HashTable線程安全,但性能差,不推薦使用。
  3. ConcurrentHashMap線程安全。
  4. ConcurrentHashMapJava7中使用segment實現,對每一個segment加鎖。
  5. ConcurrentHashMapJava8中是直接在HashMap的基礎上進行加鎖。

參考文獻:

Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
ConcurrentHashMap、HashTable、HashMap三兄弟

相關文章
相關標籤/搜索