源码解析如下:
public V put(K key, V value) {
return putVal(key, value, false);
}
//
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode()); //计算hash值
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(); //初始化数组
//通过hash值对应的数组下标得到第一个节点; 以volatile读的方式来读取table数组中的元素,保证每次拿到的数据都是最新的
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
//如果该下标返回的节点为空,则直接通过cas将新的值封装成node插入即可;如果cas失败,说明存在竞争,则进入下一次循环
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
//...
}