JDK1.7和JDK1.8中HashMap为什么是线程不安全的

参考:JDK1.7和JDK1.8中HashMap为什么是线程不安全的

(我理解的)

jdk1.7会发生死循环,数据丢失,数据覆盖这些问题,主要是因为扩容时是在transfer函数中完成数据迁移的,entry数组使用的是头插法(死循环,数据丢失)。

若两个线程同时对table进行扩容,线程A在在为桶赋值时时间片用完,此时线程B开始工作,知道扩容结束。这是old_Table已经更新为new_table,因为采用的是头插法,其实链表的链接顺序已发生改变,这是线程A继续工作,就会发生死循环,另外,若old_table中一个链表中的某些元素因为rehash被放到了其他的桶中,线程A是访问不到的,就会发生数据丢失。

jdk1.8 是在resize函数中完成了数据迁移,并且采用了尾插法,解决了死循环、数据丢失,但是仍会有数据覆盖的问题。

数据覆盖是因为hashmap在put()函数中,是先进行hash碰撞判断在插入元素的,若是两个线程A,B同时进行put操作,若线程A在hash碰撞之后、插入元素之前阻塞,接着线程B开始工作,正常完成了put操作,这是线程A接着插入元素,因为之前已经判断过hash碰撞了,所以直接插入元素,就会覆盖掉线程B正常插入的元素。

总结

HashMap的线程不安全主要体现在下面两个方面:
1.在JDK1.7中,当并发执行扩容操作时会造成环形链和数据丢失的情况。
2.在JDK1.8中,在并发执行put操作时会发生数据覆盖的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值