标签:情况 ++ cep mod lse fabs exception tab instance
1 /** 2 key:键值 3 value:值 4 onlyIfAbsent:true:如果key存在的情况下,不更新值;Flase:如果key存在的情况下,替换old value 5 **/ 6 final V putVal(K key, V value, boolean onlyIfAbsent) { 7 //不允许key或value为空 8 if (key == null || value == null) throw new NullPointerException(); 9 //在key的hascode值上重新计算key的hash值 10 //【(key.hashCode() ^ (key.hashCode() >>> 16)) & 0x7fffffff;】 11 int hash = spread(key.hashCode()); 12 int binCount = 0; 13 //CAS锁 14 for (Node<K,V>[] tab = table;;) { 15 Node<K,V> f; int n, i, fh; 16 /** 17 初始化 18 根据hash确认key的Node位置,当node为空时则CAS尝试写入,写入成功流程结束,否则进行下一次尝试 19 **/ 20 if (tab == null || (n = tab.length) == 0) 21 tab = initTable(); 22 else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { 23 if (casTabAt(tab, i, null, 24 new Node<K,V>(hash, key, value, null))) 25 break; // no lock when adding to empty bin 26 } 27 /** 28 static final int MOVED = -1; 29 如果当前位置的 hashcode == MOVED == -1, map 正在扩容,其他线程帮助扩容,也就是多线程扩容。 30 **/ 31 else if ((fh = f.hash) == MOVED) 32 tab = helpTransfer(tab, f); 33 else { 34 /** 35 利用 synchronized 锁写入数据 36 fh〉0 说明这个节点是一个链表的节点不是树的节点。 37 如果是红黑树,照树的方式插入值 38 **/ 39 V oldVal = null; 40 synchronized (f) { 41 if (tabAt(tab, i) == f) { 42 if (fh >= 0) { 43 binCount = 1; 44 //遍历链表所有结点,如果找到相同key就更新旧值,否则添加至链表尾 45 for (Node<K,V> e = f;; ++binCount) { 46 K ek; 47 if (e.hash == hash && 48 ((ek = e.key) == key || 49 (ek != null && key.equals(ek)))) { 50 oldVal = e.val; 51 if (!onlyIfAbsent) 52 e.val = value; 53 break; 54 } 55 Node<K,V> pred = e; 56 if ((e = e.next) == null) { 57 pred.next = new Node<K,V>(hash, key, 58 value, null); 59 break; 60 } 61 } 62 } 63 else if (f instanceof TreeBin) { 64 Node<K,V> p; 65 binCount = 2; 66 if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, 67 value)) != null) { 68 oldVal = p.val; 69 if (!onlyIfAbsent) 70 p.val = value; 71 } 72 } 73 } 74 } 75 /** 76 当链表长度大于8时,将链表转换为红黑树 77 **/ 78 if (binCount != 0) { 79 if (binCount >= TREEIFY_THRESHOLD) 80 treeifyBin(tab, i); 81 if (oldVal != null) 82 return oldVal; 83 break; 84 } 85 } 86 } 87 //如果是新增元素,将当前ConcurrentHashMap的元素数量+1 88 addCount(1L, binCount); 89 return null; 90 }
Java | JDK8下的ConcurrentHashMap#putValue
标签:情况 ++ cep mod lse fabs exception tab instance
原文地址:https://www.cnblogs.com/jj81/p/11479222.html