forwardingnode 是 concurrenthashmap 扩容时的协调节点,以 hash=-1、key/value=null 标记已迁移桶,并引导线程转向新表或协助迁移,实现无锁分段扩容。

ForwardingNode 是 ConcurrentHashMap 扩容时的关键协调节点,核心作用是标记已迁移的桶(bin),并引导线程转向新表或协助迁移。
标识已迁移的桶,避免重复处理
扩容过程中,原哈希表的每个桶可能被多个线程并发访问。当某个线程完成对一个桶中所有节点的迁移后,会用一个 ForwardingNode 占位该桶。这个节点的 hash 值固定为 -1,key 和 value 为 null,nextTable 指向新表。其他线程读到该节点,就能立刻识别“此桶已迁走”,不再操作旧表中的数据,防止重复迁移或读到中间状态。
引导线程参与迁移或跳转到新表
当线程在 get 或 put 过程中遇到 ForwardingNode:
- 执行 get:直接调用
find()方法,在新表(nextTable)中查找,保证读操作不阻塞、不丢失数据; - 执行 put 或 compute:先尝试协助扩容(调用
helpTransfer()),帮着迁移几个桶,再继续自己的插入逻辑; - 执行 size 或迭代:跳过 ForwardingNode,或通过它感知扩容进度,提升统计准确性。
实现无锁协作扩容的核心机制
ForwardingNode 不是锁,而是一种“状态通告+任务分发”的轻量设计:
- 它让扩容从“全表独占”变为“分段协作”,每个线程只负责自己遇到的桶;
- 无需阻塞读操作,写操作也能边扩容边进行;
- 结合 sizeCtl 的控制位(如标志位 + 协程数),多个线程可安全地推进迁移进度。
注意 ForwardingNode 不是普通数据节点
它的 key、value 均为 null,不能被当作实际映射项使用;hash 固定为 -1,会被 tabAt()、casTabAt() 等底层方法特殊识别;它只存在于扩容过渡期,扩容结束后整个表中不再存在 ForwardingNode。











