JDK1.7的HashMap的环形链表

分析扩容的核心代码

java 复制代码
// 构建新数组
Entry[] newTable = new Entry[newCapacity];
// 迁移老数组数据到新数组
transfer(newTable, initHashSeedAsNeeded(newCapacity));
// 迁移完毕后,替换老数组
table = newTable;
java 复制代码
// 迁移数据的过程
void transfer(Entry[] newTable, boolean rehash){
    int newCapacity = newTable.length;
    // 外层遍历数组
    for (Entry<k,v> e:table){
        // 遍历链表
        // 2号线程走完第二次循环,完成迁移数据(如下图2所示)
        // 1号线程走完第二次循环,发现指向的是A(如下图3所示)
        // 1号线程走完第三次循环,完成迁移数据(如下图4所示)
        while(null != e){
            Entry<K,V> next = e.next;
            // 1号线程执行到这里停止
            if(rehash){
                e.hash = null == e.key ? 0 : hash(e.key)
            }
            int i = indexFor(e.hash, newCapacity);
            e.next = newTable[i];
            newTable[i] = e;
            e = next;
        }
    }
}

图1
图2
图3
图4

JDK1.7中的HashMap是线程不安全的,可能会出现并发扩容的操作。

JDK1.7中的HashMap在迁移数据时,采用的是头插法,导致节点的next指针会有变化。

先迁移完的线程,可能会导致其他线程在扩容时,扩容到最后,将最开始的节点重新的插入到了头节点的位置,导致指针再次变化,从而形成了一个环形链表。

相关推荐
鹿角片ljp1 小时前
短信登录:基于 Session 实现(黑马点评实战)
java·服务器·spring boot·mybatis
NEXT061 小时前
数组转树与树转数组
前端·数据结构·面试
北风toto1 小时前
JDK8(JAVA)供应商说明
java·开发语言
清水白石0081 小时前
观察者模式全解析:用 Python 构建优雅的事件系统,让组件彻底解耦
java·python·观察者模式
仟濹1 小时前
【算法打卡day10(2026-02-24 周二)动态规划DP基础理论】
算法·动态规划
xiaoccii2 小时前
C++(入门版)
java·c++·算法
ADDDDDD_Trouvaille2 小时前
2026.2.23——OJ101-103题
c++·算法
月挽清风2 小时前
代码随想录第34天:动态规划
算法·动态规划
HCl__盐酸2 小时前
题解:Kitamasa 算法板子
算法