0
点赞
收藏
分享

微信扫一扫

HashMap(一)扩容死锁问题分析(JDK1.7)

吃面多放酱 2021-09-21 阅读 69

HashMap扩容死锁问题分析(JDK1.7)

  //JDK1.7扩容源代码
  void transfer(Entry[] newTable) {
        Entry[] src = table;
        int newCapacity = newTable.length;
        for (int j = 0; j < src.length; j++) {
            Entry<K,V> e = src[j];
            if (e != null) {
                src[j] = null;
                do {
                    Entry<K,V> next = e.next;
                    //重新计算hash值
                    int i = indexFor(e.hash, newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }
JDK1.7单线程扩容详解:
  • 假设A、N、M的hash值相同,发生hash碰撞,都放到3这个位置上(此处省略M的插入过程)
  • JDK1.7是采用头插法进行构建链表的,put后的结果如下:


需要扩容时:
  • 第一次do,while循环


  • 第二次do,while循环


  • 第三次do,while循环


JDK1.7多线程扩容详解:

  • 假设T1在Entry<K,V> next = e.next;这行失去了CPU使用权。
  • T2继续执行扩容(T2的扩容过程与上诉单线程类似,不同的是T1会保持指针的引用),结果如下:


  • T1开始执行:


  • T1第一次循环后的数据结构


  • T1第二次循环后的数据结构


  • T1第三次循环后的数据结构


  • 当e=null时,T1扩容结束。此时我们可以看出,链表已经成为一个环形。
  • 下次在put数据时,会循环链表查找是否有重复数据。就会形成死循环。

举报

相关推荐

0 条评论