Java基础知识---HashMap线程不安全的部分原因

想要说清楚HashMap线程不安全的事情 分两部分

JDK 1.8 以前

  • HashMap底层是数组+链表以前人尽皆知了
  • 那说一个不是人尽皆知的问题,HashMap放入新元素是采用头插法,什么是头插法呢:
    一个数组 Int[] array = {1,2,3,4}
    我们想放入一个新的元素0 就是Int[] array = {0,1,2,3,4}
  • 再说一个问题 HashMap 是有容量上限的 再超过上限的时候 但凡是一个集合都会开始扩容 当然他也不例外
    所以怎么扩容呢
    原Map 重新计算放入新的Map 注意这里也是采用头插法 采用头插法会将链表逆序
    如:现有两个线程倒班工作 一个链表如下
    a—>b—>c–>…—>z
    线程1 : 接到需要反转的命令 拿到a 此时他觉得 a后面是b 开始睡觉
    线程2 : 1睡觉我干活 我要开始反转了 那么反转后 b后面是a 干累了 我也要睡觉
    线程1: 他睡了我接着干 我好像记着 a后面是b -------此时b在梦中说 b后面是a 造成如下情况
    a–>b–>a–>…

死循环就此产生 Cpu同志骂骂咧咧的开始嚎叫

JDK 1.8优化

  • 此时 头插法变成了尾插法,讲道理肯定不会死循环了吧,确实不会死循环了
  • 但是新的问题产生了
    还是同样的工作 同样的链表
    a—>b—>c–>…—>z
    现在要在z后面添加一个 A

此次resize 顺利完成 开始添加新的元素
线程1: 这次我在后面加 刚要加A 他困了 遂放心开始睡觉
线程2: 我要加个B 然后链表变成了
a—>b—>c–>…—>z–>B
然后线程2放心的睡觉了
线程1:醒了干活 z后面应该放A 此时链表变成了
a—>b—>c–>…—>z–>A
线程2: ???? 我的B呢?

B丢了哇~~

以上就是HashMap线程不安全的部分原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值