ConcurrentHashMap
1.put方法
1.初始化,2.扩容,3.数据迁移
先判断数组table是否为null或空,是初始化;
存放当前元素的位置为空,一次CAS操作放入(不需要加锁);
当前table数组是否在扩容状态,是迁移数据
非空,给头节点加锁,判断是链表还是红黑树,放入值;
判断是否要转换为红黑树
1 public V put(K key, V value) { 2 return putVal(key, value, false); 3 } 4 5 /** Implementation for put and putIfAbsent */ 6 final V putVal(K key, V value, boolean onlyIfAbsent) { 7 //key和value都不允许null 8 if (key == null || value == null) throw new NullPointerException(); 9 int hash = spread(key.hashCode()); 10 // 用于记录相应链表的长度 11 int binCount = 0; 12 //遍历数组 13 for (Node<K,V>[] tab = table;;) { 14 Node<K,V> f; int n, i, fh; 15 //数组不存在或者没数据的情况,初始化 16 if (tab == null || (n = tab.length) == 0) 17 tab = initTable(); 18 //如果数组当前位置为null,用一次 CAS 操作将这个新值放入其中 19 else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { 20 if (casTabAt(tab, i, null, 21 new Node<K,V>(hash, key, value, null))) 22 break; // no lock when adding to empty bin 23 } 24 // 25 else if ((fh = f.hash) == MOVED) 26 tab = helpTransfer(tab, f); 27 else { 28 //如果f是头结点 29 V oldVal = null; 30 //加锁 31 synchronized (f) { 32 // 33 if (tabAt(tab, i) == f) { 34 //头结点的 hash 值大于 0,说明是链表 35 if (fh >= 0) { 36 //链表长度+1 37 binCount = 1; 38 //遍历链表 39 for (Node<K,V> e = f;; ++binCount) { 40 K ek; 41 if (e.hash == hash && 42 ((ek = e.key) == key || 43 (ek != null && key.equals(ek)))) { 44 // 如果发现了"相等"的 key,判断是否要进行值覆盖 45 oldVal = e.val; 46 if (!onlyIfAbsent) 47 e.val = value; 48 break; 49 } 50 // 到了链表的最末端,将新值放到链表的最末端 51 Node<K,V> pred = e; 52 if ((e = e.next) == null) { 53 pred.next = new Node<K,V>(hash, key, 54 value, null); 55 break; 56 } 57 } 58 } 59 //如果是一个红黑树的结构,将新值放到红黑树中 60 else if (f instanceof TreeBin) { 61 Node<K,V> p; 62 binCount = 2; 63 if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, 64 value)) != null) { 65 oldVal = p.val; 66 if (!onlyIfAbsent) 67 p.val = value; 68 } 69 } 70 } 71 } 72 //链表的长度大于8;转换为红黑树 73 if (binCount != 0) { 74 if (binCount >= TREEIFY_THRESHOLD) 75 treeifyBin(tab, i); 76 if (oldVal != null) 77 return oldVal; 78 break; 79 } 80 } 81 } 82 addCount(1L, binCount); 83 return null; 84 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律