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

相关推荐

10-09 00:50
已编辑
长江大学 算法工程师
不期而遇的夏天:1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务