如果对应的节点存在,判断这个节点的hash是不是等于MOVED(-1),说明当前节点是ForwardingNode节点,意味着有其他线程正在进行扩容,那么当前现在直接帮助它进行扩容,因此调用helpTransfer方法

else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f);

helpTransfer

从名字上来看,代表当前是去协助扩容

final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { Node<K,V>[] nextTab; int sc; // 判断此时是否仍然在执行扩容,nextTab=null的时候说明扩容已经结束了 if (tab != null && (f instanceof ForwardingNode) && (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) { int rs = resizeStamp(tab.length);//生成扩容戳 while (nextTab == nextTable && table == tab && (sc = sizeCtl) < 0) {//说明扩容还未完成的情况下不断循环来尝试将当前线程加入到扩容操作中 //下面部分的整个代码表示扩容结束,直接退出循环//transferIndex<=0表示所有的Node都已经分配了线程 //sc=rs+MAX_RESIZERS 表示扩容线程数达到最大扩容线程数//sc >>> RESIZE_STAMP_SHIFT !=rs, 如果在同一轮扩容中,那么sc无符号右移比较高位和rs的值,那么应该是相等的。如果不相等,说明扩容结束了 //sc==rs+1 表示扩容结束 if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || sc == rs + MAX_RESIZERS || transferIndex <= 0) break;//跳出循环 if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {//在低16位上增加扩容线程数 transfer(tab, nextTab);//帮助扩容 break; } } return nextTab; } return table;//返回新的数组
}

ConcurrentHashMap的源码分析-put方法第三阶段相关推荐

  1. ConcurrentHashMap的源码分析-put方法第四阶段

    这个方法的主要作用是,如果被添加的节点的位置已经存在节点的时候,需要以链表的方式加入到节点中 如果当前节点已经是一颗红黑树,那么就会按照红黑树的规则将当前节点加入到红黑树中 else { //进入到这 ...

  2. ConcurrentHashMap的源码分析-put方法第二阶段

    在putVal方法执行完成以后,会通过addCount来增加ConcurrentHashMap中的元素个数,并且还会可能触发扩容操作.这里会有两个非常经典的设计 1. 高并发下的扩容 2. 如何保证a ...

  3. ConcurrentHashMap的源码分析-put方法第四个阶段

    判断链表的长度是否已经达到临界值8. 如果达到了临界值,这个时候会根据当前数组的长度来决定是扩容还是将链表转化为红黑树.也就是说如果当前数组的长度小于64,就会先扩容.否则,会把当前链表转化为红黑树 ...

  4. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  5. HashMap与ConcurrentHashMap万字源码分析

    HashMap与ConcurrentHashMap`源码解析 JDK版本:1.7 & 1.8 ​ 开发中常见的数据结构有三种: 1.数组结构:存储区间连续.内存占用严重.空间复杂度大 优点:因 ...

  6. 【Zookeeper】源码分析之持久化(三)之FileTxnSnapLog

    一.前言 前面分析了FileSnap,接着继续分析FileTxnSnapLog源码,其封装了TxnLog和SnapShot,其在持久化过程中是一个帮助类. 二.FileTxnSnapLog源码分析 2 ...

  7. Lucene 源码分析之倒排索引(三)

    上文找到了 collect(-) 方法,其形参就是匹配的文档 Id,根据代码上下文,其中 doc 是由 iterator.nextDoc() 获得的,那 DefaultBulkScorer.itera ...

  8. MapReduce 源码分析(一)准备阶段

    MapReduce 源码分析 本篇博客根据wordCount代码进行分析底层源码的.以下称它为WC类. package com.henu;import org.apache.hadoop.conf.C ...

  9. ConcurrentHashMap的源码分析-transfer

    扩容是ConcurrentHashMap的精华之一,扩容操作的核心在于数据的转移,在单线程环境下数据的转移很简单,无非就是把旧数组中的数据迁移到新的数组.但是这在多线程环境下,在扩容的时候其他线程也可 ...

最新文章

  1. FFmpeg编译出错_img_convert 找不到
  2. 097实战 关于ETL的几种运行方式
  3. Python3 与 C# 并发编程之~ 进程篇
  4. Android 应用开发(9)---内联复杂的XML资源
  5. 【报告分享】巨量算数:疫情期间汽车专题研究洞察.pdf(附下载链接)
  6. 通过数据评估渠道用户质量的方法
  7. java基础三--IO流(1)
  8. 使用C#如何写入/读取注册表信息
  9. c语言经典50道例题---精华篇
  10. 处理word 多级标题编号不联动的问题
  11. opencv codebook背景减除
  12. view的superview的变换
  13. 一文带你了解Unity Shader-小飞侠轻功(径向模糊)
  14. java pageoffice获取word数据_PageOffice实现最简单的Java导出Word中的数据
  15. 关于Ubuntu18.04+win10双系统开机引导错误的解决方法
  16. 硬盘RAID是什么意思?有什么用?
  17. 什么是蜜罐?底层原理是什么?
  18. 为什么要使用memcache?memcache有什么作用?
  19. python中斐波那契系数实现的几种方法
  20. mybatisPlus 自定义sqlSessionFactory sql注入器失效 Invalid bound statement (not found): insertBatchSomeColumn

热门文章

  1. 关于关闭浏览器Session就丢失的讨论
  2. 70.Climbing Stairs
  3. 6-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(远程升级STM32程序,基于Wi-Fi,同时支持升级Wi-Fi,APP控制版)...
  4. 外媒评出中国最美20个景点
  5. DataSource--DBCP--C3P0--DBUtils
  6. LAMP 2.2 Apache配置静态缓存
  7. SQL语句AND 和 OR执行的优先级
  8. kde下sudo出现cannot connect to xserver解决方法
  9. 利用 IHttpHandler 自定义 HTTP 处理程序
  10. 大话设计模式—代理模式