HashMap为什么是线程不安全的

本文详细对比了JDK1.7与JDK1.8中HashMap的transfer函数实现,特别是在多线程环境下的表现差异。JDK1.7中存在环形链和数据丢失的风险,而JDK1.8通过采用尾插法解决了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. jdk1.7中HashMap的transfer函数如下:
void transfer(Entry[] newTable, boolean rehash) {
         int newCapacity = newTable.length;
         for (Entry<K,V> e : table) {
             while(null != e) {
                 Entry<K,V> next = e.next;
                 if (rehash) {
                     e.hash = null == e.key ? 0 : hash(e.key);
                 }
                 int i = indexFor(e.hash, newCapacity);
                 e.next = newTable[i];
                 newTable[i] = e;
                 e = next;
             }
         }
     }

此函数transfer是在检查到数组需要扩容后,把原先table里的数据重新计算下标后放到newtable里并且覆盖老的数组元素的过程,在jdk1.7中由于采用的是头插法的倒序排列,所以很容易形成环型链表的死循环和数据丢失的情况,而在jdk1.8中由于采用的是尾插法,所以避免了出现死循环的现象。

总结:

  1. 首先HashMap是线程不安全的,其主要体现:

#1.在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失。

#2.在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。
参考文章:https://www.cnblogs.com/developer_chan/p/10450908.html
https://www.jianshu.com/p/e2f75c8cce01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值