put
多个线程同时向Node[]的同一个位置插入时,会发生覆盖,只有一个线程的操作会被保留。
如下图源码,假如有A、B两个线程,同时在执行put且数组下标都为1,两个线程同时运行到第一个红框位置,判断tab[1]为null,A线程先执行tab[1]=NodeA,B线程再执行tab[1]=NodeB,这样B线程的操作就会覆盖A线程的。
第二个红框位置也会导致类似的问题,只不过是发生在链表上,而不是Node[]上

HashMap线程不安全的场景

 

 

resize + get
如果多个线程同时触发扩容resize,可能会形成环形链表,然后在调用get()获取一个不存在的元素时会发生死循环,导致CPU100%,JDK8已经解决了此问题。
主要原因就是,JDK7在Hash冲突时采用头插法,扩容时若旧链表的元素还会Hash到同一个新链表,那么新链表与旧链表的顺序是反的(从 A-> B变成了B -> A),在1.8后采用尾插法就不会出现这种问题,同时1.8的链表长度如果大于8就会转变成红黑树。

HashMap线程不安全的场景

size
由于++size、--size不是原子性操作,所以也会导致数据不一致。

相关文章:

  • 2021-10-31
  • 2021-08-01
  • 2021-04-13
  • 2021-04-05
  • 2021-08-14
猜你喜欢
  • 2021-04-12
  • 2022-12-23
  • 2021-11-20
  • 2021-07-29
  • 2021-09-14
  • 2022-12-23
  • 2021-06-10
相关资源
相似解决方案