请选择 进入手机版 | 继续访问电脑版

热点推荐

查看: 203|回复: 1

HashMap多线程导致死循环的问题

[复制链接]
  • TA的每日心情
    开心
    昨天 09:39
  • 签到天数: 262 天

    [LV.8]以坛为家I

    2万

    主题

    2万

    帖子

    8万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    88009
    发表于 2019-10-23 21:58:48 | 显示全部楼层 |阅读模式
    在多线程下,进行put操作会导致HashMap死循环,原因在于HashMap的扩容resize()方法。由于扩容是新建一个数组,复制原数据到数组。由于数组下标挂有链表,所以需要复制链表,但是多线程操作有可能导致环形链表。复制链表的过程如下:
    以下模拟2个线程同时扩容。假设,当前HashMap的空间为2(临界值为1),hashCode分别为0和1,在散列地址0处有元素A和B,这时候要添加元素C,C经过Hash计算,得到散列地址为1,这时候由于超过了临界值,空间不够,需要调用resize方法进行扩容,那么在多线程条件下,会出现条件竞争,模拟过程如下:
    线程一:读取到当前的HashMap的情况,在准备扩容时,线程二介入


    线程二:读取HashMap,进行扩容


    线程一:继续执行


    这个过程为,先将A复制到新的hash表中,然后接着复制B到链头(A的前边: B.next=A),本来B.next=null,到此也就结束了(跟线程二一样的过程),但是,由于线程二扩容的原因,将B.next=A,所以,这里继续复制A,让A.next=B,由此,环形链表出现:B.next=A;A.next=B
    注意:jdk1.8已经解决了死循环的问题。

    回复

    使用道具 举报

    该用户从未签到

    6

    主题

    49

    帖子

    104

    积分

    注册会员

    Rank: 2

    积分
    104
    发表于 2020-3-14 09:01:18 | 显示全部楼层
    java吧给力
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    快速回复 返回顶部 返回列表