put
final v putval(k key, v value, boolean onlyifabsent)
//在上一步的else if中 f 不為null時,則判斷f的hash值是否為moved,即-1,如果為-1,表示正在擴容
else if ((fh = f.hash) == moved)
//協助資料遷移
tab = helptransfer(tab, f);
else
break;
}nodepred = e;
//遍歷到最後乙個節點,將新插入的節點賦值給最後乙個節點的next屬性。即新插敘的節點放到了鍊錶尾部。
if ((e = e.next) == null) }}
> 0 鏈轉書操作。 fh小於0,但是不為-1,判斷f是否為樹節點。
//將 k v 組合成乙個node節點,節點中包含hash,key,value,next(null)屬性。
1.castabat(tab, i, null,new node(hash, key, value, null));
2.static final boolean castabat(node tab, int i, nodec, nodev)
解釋:在陣列table的索引i處,如果為null,則設定為node(c)。
初始化
private final node inittable()
} finally
break;}}
return tab;
}
u.compareandswapint(this, sizectl, sc, -1)
方法解釋:this表示當前物件,sizectl表示sizectl在記憶體的偏移量,說白了就是sizectl在記憶體中的位置,sc就是sizectl的值。
就是說,先根據sizectl找到sizectl的位置,看看sizectl是不是-1,即如果sc == -1,則返回false,sc != -1 ,就把sizectl更改為-1,返回true表示獲取到了初始化的權利。
helptransfer(tab, f);
addcount分兩步:一.數量加1. 二.校驗是否擴容。看**。
private final void addcount(long x, int check)
//as加1成功,check小於等1,return。
if (check <= 1)
return;
//as加1成功,記錄as的總數。即size的大小
s = sumcount();
}//執行2 //二:校驗是否擴容
if (check >= 0)
//第乙個執行緒開始擴容時執行。將sizectl設定為負數。
else if (u.compareandswapint(this, sizectl, sc,
(rs << resize_stamp_shift) + 2))
transfer(tab, null);
s = sumcount();}}
}
fulladdcount();
private final void fulladdcount(long x, boolean wasuncontended)
boolean collide = false; // true if last slot nonempty
for (;;)
} finally
if (created)
break;
continue; // slot is now non-empty}}
collide = false;
}else if (!wasuncontended) // cas already known to fail
wasuncontended = true; // continue after rehash
else if (u.compareandswaplong(a, cellvalue, v = a.value, v + x))
break;
else if (countercells != as || n >= ncpu)
collide = false; // at max size or stale
else if (!collide)
collide = true;
else if (cellsbusy == 0 &&
u.compareandswapint(this, cellsbusy, 0, 1))
} finally
collide = false;
continue; // retry with expanded table
}h = threadlocalrandom.advanceprobe(h);
}//初始化countercells,cellsbusy表示cc是否在初始化或擴容,值為0和1.
else if (cellsbusy == 0 && countercells == as &&
u.compareandswapint(this, cellsbusy, 0, 1))
} finally
if (init)
break;
//如果沒有獲取初始化的權利,則嘗試basecount加1,如果失敗,則進行自旋。
else if (u.compareandswaplong(this, basecount, v = basecount, v + x))
break; // fall back on using base}}
ConcurrentHashMap原始碼分析
hashmap 先說hashmap,hashmap是執行緒不安全 的,在併發環境下,可能會形成環狀鍊錶 hashtable hashtable和hashmap的實現原理幾乎一樣,差別無非是1.hashtable不允許key和value為null 2.hashtable是執行緒安全的。但是hashta...
ConcurrentHashMap原始碼詳解
成員變數private static final int maximum capacity 1 30 private static final int default capacity 16 static final int max array size integer.max value 8 pr...
concurrentHashMap原始碼分析
concurrenthashmap是hashmap的執行緒安全版本,內部也是使用 陣列 鍊錶 紅黑樹 的結構來儲存元素。相比於同樣執行緒安全的hashtable來說,效率等各方面都有極大地提高。在這裡可以使用上篇那個 進行測試,根據結果可以知道concurrenthashmap是執行緒安全的,由於分...