Java | JDK8下的ConcurrentHashMap#putValue
Posted jj81
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java | JDK8下的ConcurrentHashMap#putValue相关的知识,希望对你有一定的参考价值。
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的主要内容,如果未能解决你的问题,请参考以下文章