美文网首页
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