1.putVal
cas+自旋保证线程安全
处理某个槽位时使用synchronized
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>implements ConcurrentMap<K,V>, Serializable {static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);}static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,Node<K,V> c, Node<K,V> v) {return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);} final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) {throw new NullPointerException();}int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0){tab = initTable();} else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {//tab[i]//创建Node,放到tab[i]if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null))){break; // no lock when adding to empty bin}} else if ((fh = f.hash) == MOVED){//表示正在扩容tab = helpTransfer(tab, f); //协助扩容} else {V oldVal = null;synchronized (f) { //对tab[i]加锁if (tabAt(tab, i) == f) {if (fh >= 0) {//hash>=0 表示是普通的链表结构binCount = 1;for (Node<K,V> e = f;; ++binCount) {K ek;if (e.hash == hash &&((ek = e.key) == key ||(ek != null && key.equals(ek)))) {oldVal = e.val;//找到key一样的节点,更新valif (!onlyIfAbsent){e.val = value;}break;}Node<K,V> pred = e;if ((e = e.next) == null) {//遍历到链表结尾也没有key相等的//放到链表尾pred.next = new Node<K,V>(hash, key, value, null);break;}}} else if (f instanceof TreeBin) {//如果是treeNode<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,value)) != null) {oldVal = p.val;if (!onlyIfAbsent){p.val = value;}}} else if (f instanceof ReservationNode){throw new IllegalStateException("Recursive update");}}}if (binCount != 0) {//看是否需要扩容if (binCount >= TREEIFY_THRESHOLD){treeifyBin(tab, i);}if (oldVal != null){return oldVal;}break;}}}addCount(1L, binCount);//维护size和看是否需要扩容return null;}
}