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     }

猜你喜欢

转载自www.cnblogs.com/jj81/p/11479222.html