java中ConcurrentHashMap的扩容机制问题

JDK8中,扩容函数transfer中有如下一段代码,如果槽内的结点为链表结点,把原链表的结点按照某位的元素是否为1,划分为两个链表,分别放置在nextTab[i]和nextTab[n+i]位置上,
问题来了:代码中会将链表反序输出,但是我自己理解的是一个链表是源链表的反序,一个链表有一半是反序一半是源数组的顺序,我看别人的博客说是一个链表是反序,一个链表是源序列,这个怎样理解。还有源码这样处理的原因是啥

if (fh >= 0) {
            int runBit = fh & n;
            ConcurrentHashMap.Node<K,V> lastRun = f;
            for (ConcurrentHashMap.Node<K,V> p = f.next; p != null; p = p.next) {
                int b = p.hash & n;
                if (b != runBit) {
                    runBit = b;
                    lastRun = p;
                }
            }
            if (runBit == 0) {
                ln = lastRun;
                hn = null;
            }
            else {
                hn = lastRun;
                ln = null;
            }
            for (ConcurrentHashMap.Node<K,V> p = f; p != lastRun; p = p.next) {
                int ph = p.hash; K pk = p.key; V pv = p.val;
               *if ((ph & n) == 0)*
*                    ln = new ConcurrentHashMap.Node<K,V>(ph, pk, pv, ln);*
*                else*
*                    hn = new ConcurrentHashMap.Node<K,V>(ph, pk, pv, hn);*
            }
            setTabAt(nextTab, i, ln);
            setTabAt(nextTab, i + n, hn);
            setTabAt(tab, i, fwd);
            advance = true;
        }
全部评论
没有反序,就是从链表头开始遍历,根据是否为1,分为两个链表
点赞 回复 分享
发布于 2017-07-16 11:04
楼主你好,我有个问题。比如说,扩容期间,如果在正在迁移的hash桶位置处突然有个put操作,请问这时候应该,A:“put操作阻塞,等迁移操作执行完毕再插入”;B:“迁移操作先阻塞,等插入操作插完了,在进行迁移”。请问是A还是B?
点赞 回复 分享
发布于 2019-07-31 16:41

相关推荐

神哥了不得:你简历字体有点不太协调呀,下面的字实在太小了呀,而且项目也不太行,建议换几个高质量的项目,面试会多很多
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务