java計算hash值,Java中HashMap原理

 2023-11-30 阅读 35 评论 0

摘要:HashMap的底層是數組+鏈表,(很多人應該都知道了) JDK1.7的是數組+鏈表 (1.7只是一個例子,以前的話也是這樣后面就以1.7為例子了) 首先是一個數組,然后數組的類型是鏈表 元素是頭插法 JDK1.8的是數組+鏈表 或者

HashMap的底層是數組+鏈表,(很多人應該都知道了)
JDK1.7的是數組+鏈表
(1.7只是一個例子,以前的話也是這樣后面就以1.7為例子了)
首先是一個數組,然后數組的類型是鏈表
元素是頭插法
JDK1.8的是數組+鏈表 或者 數組+紅黑樹
首先是一個數組,然后數組的類型是鏈表
在鏈表的元素大于8的時候,會變成紅黑樹
在紅黑樹的元素小于6的時候會變成鏈表
元素進行尾插

HaspMap的數組默認大小為16
數組也叫做Hash桶
(貌似聽說這個值和阿里巴巴Java開發手冊好像有點關系)

HashMap元素的下標是
HashCode(元素) & (數組的長度-1)

HashMap的擴容 Resize

java計算hash值?擴容的話,這里有一個值叫做loadFactor(閾值),默認值為0.75;
當數組的 元素數量>數組大小(默認16)* loadFactor(默認0.75)
就會觸發擴容,擴容是二倍擴容的 (默認是16擴容后就是32)
這時原來每個元素的下標也會改變的(因為數組的長度變了)
然后就要把每個元素重新分配下標,重新加入鏈表或者紅黑樹

HashMap線程不安全
在put的時候,Resize(擴容)會造成數據的覆蓋
JDK1.7 因為是頭插法,可能會造成循環鏈表
JDK1.8 是尾插法

使用HashMap怎么才能讓他線程安全
使用ConcurrentHashMap,
JDK1.7的是分段數組,有Segment鎖(繼承于ReentrantLock)加速一小段保證并發
JDK1.8 是和HashMap一樣了,數組+鏈表(或者紅黑樹)
Synchronized(鎖)and CAS(compare and swap)
(JVM在1.6對Synchronize的優化很好)
CAS通俗易懂,比較并替換
(CAS是一種無鎖算法,CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做)
(無鎖化的修改值的操作,他可以大大降低鎖代理的性能消耗。這個算法的基本思想就是不斷地去比較當前內存中的變量值與你指定的 一個變量值是否相等,如果相等,則接受你指定的修改的值,否則拒絕你的操作。因為當前線程中的值已經不是最新的值,你的修改很可能會覆蓋掉其他線程修改的結果。這一點與樂觀鎖,SVN的思想是比較類似的)

使用HashTable(基本是廢棄的)
HashTable就是把HashMap套上了一個Synchronized

Collections.synchronizedMap()包裝
使用synchronized 加上,但是這個是對某個Hash桶(數組的某個值)加鎖,并不是整個map加鎖,在鎖定的時候別的線程也可以進行訪問

?

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/185463.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息