日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一文读懂JDK7,8,JD9的HashMap,HashTable,ConcurrentHashMap及他们的区别

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文读懂JDK7,8,JD9的HashMap,HashTable,ConcurrentHashMap及他们的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內容和標題一樣長哦,人家寫了好久的。如無特別指明,內容對應的源碼是jdk1.7(后面會和1.8對比)

?

1:hashmap簡介(如下,數組-鏈表形式)


HashMap的存儲結構

? ? ??圖中,紫色部分即代表哈希表,也稱為哈希數組(默認數組大小是16,每對key-value鍵值對其實是存在map的內部類entry里的),數組的每個元素都是一個單鏈表的頭節點,跟著的綠色鏈表是用來解決沖突的,如果不同的key映射到了數組的同一位置處,就會采用頭插法將其放入單鏈表中。

?

2:hashmap原理(即put和get原理)


2.1 put原理

1.根據key獲取對應hash值:int hash = hash(key.hash.hashcode())

2.根據hash值和數組長度確定對應數組引int?i?=?indexFor(hash,?table.length);?簡單理解就是i = hash值%模以 數組長度(其實是按位與運算)。如果不同的key都映射到了數組的同一位置處,就將其放入單鏈表中。且新來的是放在頭節點。

?

2.2 get原理

1.通過hash獲得對應數組位置,遍歷該數組所在鏈表(key.equals())

?

3.1:hashcode相同,沖突怎么辦?

“頭插法”,放到對應的鏈表的頭部。

?

3.2:為什么是頭插法(為什么這么設計)?

因為HashMap的發明者認為,后插入的Entry被查找的可能性更大,所以放在頭部(因為get()查詢的時候會遍歷整個鏈表)。

?

4.1:hashmap的默認數組長度是多少?

默認為16

?

4.2:為什么?

之所以選擇16,是為了服務于從key映射到index的hash算法(看下面)。

?

5.1:hashmap達到默認負載因子(0.75)怎么辦?

自動雙倍擴容,擴容后重新計算每個鍵值對位置。且長度必須為16或者2的冪次

?

5.2:為啥要16或者2的冪次?

若不是16或者2的冪次,位運算的結果不夠均勻分布,顯然不符合Hash算法均勻分布的原則。

反觀長度16或者其他2的冪,Length-1的值是所有二進制位全為1,這種情況下,index的結果等同于HashCode后幾位的值。只要輸入的HashCode本身分布均勻,Hash算法的結果就是均勻的。

?

6.1:hashmap是線程安全的嗎?

不是。

?

6.2 :為什么?

因為沒加鎖

?

6.3: 那在并發時會導致什么問題?

hashmap在接近臨界點時,若此時兩個或者多個線程進行put操作,都會進行resize(擴容)和ReHash(為key重新計算所在位置),而ReHash在并發的情況下可能會形成鏈表環。在執行get的時候,會觸發死循環,引起CPU的100%問題。

注:jdk8已經修復hashmap這個問題了,jdk8中擴容時保持了原來鏈表中的順序。但是HashMap仍是非并發安全,在并發下,還是要使用ConcurrentHashMap。

?

6.4: 如何判斷有環形表?

最優:首先創建兩個指針A和B(在java里就是兩個對象引用),同時指向這個鏈表的頭節點。然后開始一個大循環,在循環體中,讓指針A每次向下移動一個節點,讓指針B每次向下移動兩個節點,然后比較兩個指針指向的節點是否相同。如果相同,則判斷出鏈表有環,如果不同,則繼續下一次循環。

理解例子:在一個環形跑道上,兩個運動員在同一地點起跑,一個運動員速度快,一個運動員速度慢。當兩人跑了一段時間,速度快的運動員必然會從速度慢的運動員身后再次追上并超過,原因很簡單,因為跑道是環形的。

7: hashmap ?和 ?hashtable ?區別?

兩者的區別線程效率數組默認值null值hashmap不安全更高16key-value都允許hashtable安全略低11不允許(拋異常)

?

8.0:那hashmap不安全,hashtable性能又低,怎么辦?

用concurrenthashmap,即保證安全,性能又可以保證。

?

8.1:那concurrenthashmap究竟是什么?

整個ConcurrentHashMap的結構如下:

理解:hashmap是有entry數組組成,而concurrenthashmap則是Segment數組組成。而Segment又是什么呢?Segment本身就相當于一個HashMap。

同HashMap一樣,Segment包含一個HashEntry數組,數組中的每一個HashEntry既是一個鍵值對,也是一個鏈表的頭節點。

單一的Segment結構如下(是不是看著就是hashmap):

像這樣的Segment對象,在ConcurrentHashMap集合中有多少個呢?有2的N次方個,共同保存在一個名為segments的數組當中。

可以說,ConcurrentHashMap是一個二級哈希表。在一個總的哈希表下面,有若干個子哈希表。(這樣類比理解多個hashmap組成一個cmap)

?

8.2:那他的put和get方法呢?

Put方法:

1.為輸入的Key做Hash運算,得到hash值。

2.通過hash值,定位到對應的Segment對象

3.獲取可重入鎖

4.再次通過hash值,定位到Segment當中數組的具體位置。

5.插入或覆蓋HashEntry對象。

6.釋放鎖。

Get方法:

1.為輸入的Key做Hash運算,得到hash值。

2.通過hash值,定位到對應的Segment對象

3.再次通過hash值,定位到Segment當中數組的具體位置。

由此可見,和hashmap相比,ConcurrentHashMap在讀寫的時候都需要進行二次定位。先定位到Segment,再定位到Segment內的具體數組下標。

?

9: ? ? hashmap ?和 ? ? concurrenthashmap區別?

線程: ? 不安全 ? ? ? ? ? ? ? ? ? 安全

?

10.1:為啥concurrenthashmap和hashtable都是線程安全,但是前者性能更高

因為前者是用的分段鎖,根據hash值鎖住對應Segment對象,當hash值不同時,使其能實現并行插入,效率更高,而hashtable則會鎖住整個map。

如何理解并行插入:當cmap需要put元素的時候,并不是對整個map進行加鎖,而是先通過hashcode來知道他要放在那一個分段(Segment對象)中,然后對這個分段進行加鎖,所以當多線程put的時候,只要不是放在同一個分段中,就實現了真正的并行的插入。

但是,在統計size的時候,就是獲取concurrenthashmap全局信息的時候,就需要獲取所有的分段鎖才能統計(即效率稍低)。

?

10.2:分段鎖的設計解決的是什么問題?

分段鎖的設計目的是細化鎖的粒度,當操作不需要更新整個數組的時候,就僅僅針對數組中的一部分行加鎖操作。

?

11:JDK1.7的hashmap和JDK1.8的hashmap的區別(即1.8做了哪些優化)?

1.為了加快查詢效率,java8的hashmap引入了紅黑樹結構,當數組長度大于默認閾值64時,且當某一鏈表的元素>8時,該鏈表就會轉成紅黑樹結構,查詢效率更高。(問題來了,什么是紅黑樹?什么是B+樹?(mysql索引有B+樹索引)什么是B樹?什么是二叉查找樹?)數據結構方面的知識點會更新在【數據結構專題】,這里不展開。

這里只簡單的介紹一下紅黑樹:

紅黑樹是一種自平衡二叉樹,擁有優秀的查詢和插入/刪除性能,廣泛應用于關聯數組。對比AVL樹,AVL要求每個結點的左右子樹的高度之差的絕對值(平衡因子)最多為1,而紅黑樹通過適當的放低該條件(紅黑樹限制從根到葉子的最長的可能路徑不多于最短的可能路徑的兩倍長,結果是這個樹大致上是平衡的),以此來減少插入/刪除時的平衡調整耗時,從而獲取更好的性能,而這雖然會導致紅黑樹的查詢會比AVL稍慢,但相比插入/刪除時獲取的時間,這個付出在大多數情況下顯然是值得的。好了我知道你們看暈了,移步去看看我的【數據結構專題】吧。

2.優化擴容方法,在擴容時保持了原來鏈表中的順序,避免出現死循環

?

12:JDK1.7的concurrenthashmap和JDK1.8又有什么區別?

1.8的實現已經拋棄了Segment分段鎖機制,利用Node數組+CAS+Synchronized來保證并發更新的安全,底層采用數組+鏈表+紅黑樹的存儲結構。

java給我們帶來了并發安全的ConcurrentHashMap,它的實現是依賴于 Java 內存模型,所以我們在了解 ConcurrentHashMap 的之前必須了解一些底層的知識:

  • java內存模型

  • java中的Unsafe

  • java中的CAS

  • java同步器AQS

  • ReentrantLock

  • 所以在這里我不準備深入講解ConcurrentHashMap ,我會在【并發編程】專題通過一步步詳解并發基礎,從java內存模型,synchronized,volatile,Unsafe到CAS,AQS,各種鎖再到JUC并發包相關。

    先放張java內存模型的思維導圖勾引一波,光java內存模型一個點就有這么多要講的了。

    ?

    13:那么問題來了,什么是CAS?

    關于CAS方面的知識點,又會涉及到ABA問題,又可以扯到樂觀鎖悲觀鎖,鎖編程,AQS等,相關內容將更新在【并發編程專題】,這里不做展開

    14:那1.9的呢?

    瞄了一眼,好像和1.8的沒啥區別,這里不做展開....(嚶嚶嚶,別打臉.)

    總結

    以上是生活随笔為你收集整理的一文读懂JDK7,8,JD9的HashMap,HashTable,ConcurrentHashMap及他们的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 人人看人人模 | 夜夜高潮夜夜爽 | 亚洲一区有码 | 日本性网站 | 四虎音影 | 黄色片网站免费看 | 欧美日韩麻豆 | 成人国产av一区二区三区 | 99久久99久久精品国产片 | 欧美三级理论片 | 天天操免费视频 | 翔田千里x88aⅴ | 999精品视频在线观看 | 久久久天堂国产精品女人 | 婷婷色六月 | 国产精品三级久久久久久电影 | 国产成人精品在线视频 | 少妇闺蜜换浪荡h肉辣文 | 免费的理伦片在线播放 | 精品三级| 寂寞午夜影院 | 国产精品jizz在线观看美国 | 探花视频在线版播放免费观看 | www.亚洲激情 | av资源免费 | 日韩在线视频观看免费 | sm久久捆绑调教精品一区 | 久久久精品国产sm调教 | 色欲无码人妻久久精品 | 尤物193.com| 免费精品无码AV片在线观看黄 | 91精品国产自产精品男人的天堂 | 韩国裸体网站 | 天天操天天爱天天干 | av网站在线免费播放 | 亚洲v国产v| www黄色com| 亚洲一区区| 人成免费 | 国产精品视频 | 国产老女人乱淫免费可以 | 欧美xxxx8888 | 色呦呦在线视频 | 欧美伊人久久 | 午夜污污 | 少妇精品无码一区二区免费视频 | 国产一级在线播放 | 久久夜精| 国产这里有精品 | 国产 日韩 一区 | 久草超碰| 天堂аⅴ在线最新版在线 | 成 人 免费 黄 色 | 国产盗摄视频在线观看 | 日本www高清 | 成人在线观看视频网站 | 在线天堂av | 男女透逼视频 | 欧美日韩一区二区三 | xxxxxxxx黄色片 | 日本三级黄色录像 | 国产黄视频网站 | 日韩网站免费 | 77777av| 亚洲国产欧美另类 | 国产欧美一区二区精品性色 | xxxx少妇| 长腿校花无力呻吟娇喘的视频 | 青娱网电信一区电信二区电信三区 | 久久久999国产精品 天堂av中文在线 | 中文字幕丝袜诱惑 | 天堂在线中文资源 | 中文字幕无产乱码 | 深爱五月激情五月 | 成人av色 | 久久理论电影 | 午夜影院日本 | 韩国女主播一区二区 | 欧洲成人一区二区三区 | 一级二级在线观看 | 日韩一区二区三区精品视频 | 亚洲a毛片 | 国产色综合网 | 亚洲日日骚 | 亚洲aaa| 91综合视频| 欧美一区二区在线看 | 色综合久久久久久久 | 精品国产高清在线观看 | 大桥未久中文字幕 | 国产一级一级国产 | 日韩少妇av | 欧美福利片在线观看 | 日韩在线高清 | 亚洲综合色小说 | 中国亚洲老头同性gay男男… | 无遮挡裸光屁屁打屁股男男 | 帮我拍拍漫画全集免费观看 | 久草视频福利 |