Java集合:HashMap线程不安全?有哪些表现?

HashMap是线程不安全的!主要表现在多线程情况下:

1)hash冲突时,put方法不是同步的先存的值会被后存的值覆盖。(1.7和1.8都有的表现)

2)在resize的时候,可能会导致死循环(环形链表)(仅1.7会有的表现,因为其头插法导致)


让我们先来了解一下HashMap的底层存储结构,HashMap底层是一个Entry数组,一旦发生Hash冲突的的时候,HashMap采用拉链法解决碰撞冲突,Entry内部的变量:

[java] view plain copy

 

  1. final Object key;  
  2. Object value;  
  3. Entry next;  
  4. int hash;  


        通过Entry内部的next变量可以知道使用的是链表,这时候我们可以知道,如果多个线程,在某一时刻同时操作HashMap并执行put操作,而有大于两个key的hash值相同,如图中a1、a2,这个时候需要解决碰撞冲突,而解决冲突的办法上面已经说过,对于链表的结构在这里不再赘述,暂且不讨论是从链表头部插入还是从尾部初入,这个时候两个线程如果恰好都取到了对应位置的头结点e1,而最终的结果可想而知,a1、a2两个数据中势必会有一个会丢失,如图所示:

 

再来看下put方法

 

[java] view plain copy

 

  1. public Object put(Object obj, Object obj1)  
  2.     {  
  3.         if(table == EMPTY_TABLE)  
  4.             inflateTable(threshold);  
  5.         if(obj == null)  
  6.             return putForNullKey(obj1);  
  7.         int i = hash(obj);  
  8.         int j = indexFor(i, table.length);  
  9.         for(Entry entry = table[j]; entry != null; entry = entry.next)  
  10.         {  
  11.             Object obj2;  
  12.             //搜索同一个桶的链表上是否有相同key的entry,有则直接替换value
  13.             if(entry.hash == i && ((obj2 = entry.key) == obj || obj.equals(obj2)))  
  14.             {  
  15.                 Object obj3 = entry.value;  
  16.          
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值