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

热点推荐

    查看: 529|回复: 2

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

    [复制链接]
  • TA的每日心情
    开心
    4 天前
  • 签到天数: 361 天

    [LV.8]以坛为家I

    5万

    主题

    5万

    帖子

    16万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    160047
    发表于 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的情况,在准备扩容时,线程二介入
    / b- v; X+ d4 J6 t' w

    0 Q+ w4 b5 ^5 U# d4 s
    线程二:读取HashMap,进行扩容
    : N, s  `  W; x) j" k

    - g7 p5 Z* d0 F/ B9 m
    线程一:继续执行

    4 C* u" D& _1 l- I" _6 D6 P9 U
    & c( K, l$ {) x4 E; T! a
    这个过程为,先将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已经解决了死循环的问题。

    ; }; ?/ I  @1 E" ~% o
    回复

    使用道具 举报

    该用户从未签到

    6

    主题

    120

    帖子

    246

    积分

    中级会员

    Rank: 3Rank: 3

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

    使用道具 举报

    该用户从未签到

    9

    主题

    123

    帖子

    255

    积分

    中级会员

    Rank: 3Rank: 3

    积分
    255
    发表于 2020-11-12 14:42:56 | 显示全部楼层
    66666,很棒
    回复

    使用道具 举报

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

    本版积分规则

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