Skip to content

Commit e5c5905

Browse files
authored
Merge pull request itwanger#30 from arglone/patch-2
ConcurrentHashMap 源码分析中的小问题~ Update ConcurrentHashMap.md
2 parents 6ab6167 + ee92c1f commit e5c5905

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

docs/thread/ConcurrentHashMap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
591591
if (tabAt(tab, i) == f) {
592592
Node<K,V> ln, hn;
593593
if (fh >= 0) {
594-
//4.3 处理当前节点为链表的头结点的情况,构造两个链表,一个是原链表 另一个是原链表的反序排列
594+
//4.3 处理当前节点为链表的头结点的情况,根据最高位为1还是为0(最高位指数组长度位),将原链表拆分为两个链表,分别放到新数组的i位置和i+n位置。这里还通过巧妙的处理措施,使得原链表中的一部分能直接平移到新链表(即lastRun及其后面跟着的一串节点),剩下部分才需要通过new方式克隆移动到新链表中(采用头插法)。
595595
int runBit = fh & n;
596596
Node<K,V> lastRun = f;
597597
for (Node<K,V> p = f.next; p != null; p = p.next) {
@@ -612,7 +612,7 @@ private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
612612
for (Node<K,V> p = f; p != lastRun; p = p.next) {
613613
int ph = p.hash; K pk = p.key; V pv = p.val;
614614
if ((ph & n) == 0)
615-
ln = new Node<K,V>(ph, pk, pv, ln);
615+
ln = new Node<K,V>(ph, pk, pv, ln); //可以看到是逆序插入新节点的(头插)
616616
else
617617
hn = new Node<K,V>(ph, pk, pv, hn);
618618
}
@@ -675,7 +675,7 @@ private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
675675
根据运算得到当前遍历的数组的位置i,然后利用tabAt方法获得i位置的元素再进行判断:
676676

677677
1. 如果这个位置为空,就在原table中的i位置放入forwardNode节点,这个也是触发并发扩容的关键点;
678-
2. 如果这个位置是Node节点(fh>=0),如果它是一个链表的头节点,就构造一个反序链表,把他们分别放在nextTable的i和i+n的位置上
678+
2. 如果这个位置是Node节点(fh>=0),如果它是一个链表的头节点,就把这个链表分裂成两个链表,把它们分别放在nextTable的i和i+n的位置上
679679
3. 如果这个位置是TreeBin节点(fh<0),也做一个反序处理,并且判断是否需要untreefi,把处理的结果分别放在nextTable的i和i+n的位置上
680680
4. 遍历过所有的节点以后就完成了复制工作,这时让nextTable作为新的table,并且更新sizeCtl为新容量的0.75倍 ,完成扩容。设置为新容量的0.75倍代码为 `sizeCtl = (n << 1) - (n >>> 1)`,仔细体会下是不是很巧妙,n<<1相当于n右移一位表示n的两倍即2n,n>>>1左右一位相当于n除以2即0.5n,然后两者相减为2n-0.5n=1.5n,是不是刚好等于新容量的0.75倍即2n*0.75=1.5n。最后用一个示意图来进行总结(图片摘自网络):
681681

0 commit comments

Comments
 (0)