美文网首页
3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画

3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画

作者: Jeffery大侠 | 来源:发表于2018-12-17 22:19 被阅读0次

这个问题,主要参考的程序员小灰的博客:

程序员小灰2017年原创汇总

一:简单的介绍一下啊HashMap:

1.1:HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。

1.2:计算位置:对key.hashCode进行hash运算,得到的值进行位运算。

1.3:HashMap数组的每一个元素不止是一个Entry对象,也是一个链表的头节点。每一个Entry对象通过Next指针指向它的下一个Entry节点。当新来的Entry映射到冲突的数组位置时,只需要插入到对应的链表即可;

需要注意的是,新来的Entry节点插入链表时,使用的是“头插法,也就是查到链表的头部,是因为HashMap的发明者认为,后插入的Entry被查找的可能性更大

1.4:初始长度是16,并且每次扩展时候,长度必须是2的幂。因为2的幂-1对应的二进制末尾总是是1111,这样,和key.hash做“与”运算的时候,只要输入的HashCode本身分布均匀,Hash算法的结果就是均匀的。


二:高并发下的HashMap

2.1:当 HashMap.Size   >=  Capacity * LoadFactor 时候,HashMap进行Resize

          影响发生Resize的因素有两个:

            1.Capacity

                    HashMap的当前长度。上一期曾经说过,HashMap的长度是2的幂。

            2.LoadFactor

                    HashMap负载因子,默认值为0.75f。

            也就是现有长度(size)是目前容量的0.75的时候,扩容。

2.2:Resize步骤:

        1.扩容

            创建一个新的Entry空数组,长度是原数组的2倍。

        2.ReHash

            遍历原Entry数组,把所有的Entry重新Hash到新数组。为什么要重新Hash呢?因为长度扩大以后,Hash的规则也随之改           变。

        让我们回顾一下Hash公式:

        index =  HashCode(Key) &  (Length - 1) 

        当原数组长度为8时,Hash运算是和111B做与运算;新数组长度为16,Hash运算是和1111B做与运算。Hash结果显然不同。

2.3:reHash带来的问题

        看代码:

相关文章

网友评论

      本文标题:3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画

      本文链接:https://www.haomeiwen.com/subject/hqfvhqtx.html