HashMap为什么是线程不安全的

HashMap的工作原理是近年来常见的Java面试题。几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此特殊呢?是因为这道题考察的深度很深。这题经常出现在高级或中高级面试中。投资银行更喜欢问这个问题


在JDK1.6和JDK1.7,hashMap使用数组+链表实现(使用链表来处理hash冲突),同一个hash值的链表都存储在一个链表里。

但是当一个数组元素中,链表的节点过多,通过key值去查找效率会很低。

在JDK1.8之后,当链表阈值超过8时,就会将链表转换成红黑树。


1.当我们push(key,value)的时候,先对key调用hashCode()方法,返回的hash值用于找到bucket位置(数组),存储Entry对象(key和value)链表形式。


2.如果不同的key发生hash冲突的时候,因为bucket位置相同,所以将Entry对象以链表形式存储。


3.如果不同的key,而两个hashCode相同,如何通过get(key)获取对象。会遍历链表,通过keys.equals(),去找唯一的对象。


4.链表是一个对象引用下一个对象。那么并发执行,可能会发生替换。


如果HashMap的大小超过了负载因子的容量。

负载因子(load factor)

默认0.75,也就是说当一个map填满了75%的bucket的时候,和其他集合类一样,创建原来map的2倍大小的bucket,将原来的对象放入。


重新调整HashMap存在什么问题?

存在条件竞争,因为如果两个线程都发现HashMap调整大小,它们会同时尝试调整大小。存储在链表的元素的次序会反过来,因为移动到新的bucket位置时,HashMap将不会将元素放在链表尾部,而是放在头部。这是为了避免尾部遍历。如果竞争了就死循环了。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值