3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)?

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

程序员小灰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带来的问题

        看代码:



©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Deve...
    周二倩你一生阅读 5,031评论 0 5
  • 一、HashMap概述 HashMap基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用nul...
    小陈阿飞阅读 3,788评论 0 2
  • Java集合:HashMap源码剖析 一、HashMap概述 二、HashMap的数据结构 三、HashMap源码...
    记住时光阅读 4,023评论 2 1
  • 其实从一开始 我就不知道自己要的到底是什么 上天就是这样的不公平 没办法去改变什么 那就只能改变自己 现在过的每一...
    7d24370db6d2阅读 3,923评论 0 1
  • 时间过的真快转眼我从学弟变成了学长,我也糊里糊涂的去面试了劳动小组长,莫名其妙的就同过来面试。最开始我是奔着工资去...
    思想根基阅读 1,215评论 0 0