ConcurrentSkipListMap源码---JDK1.8

Posted emoji-emoji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ConcurrentSkipListMap源码---JDK1.8相关的知识,希望对你有一定的参考价值。

 

 

 

 private V doPut(K key, V value, boolean onlyIfAbsent) {
        Node<K,V> z;             // added node
        if (key == null)
            throw new NullPointerException();
        Comparator<? super K> cmp = comparator;
        outer: for (;;) {
            //找到key对应的前继节点b
            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                //如果n不为null
                if (n != null) {
                    Object v; int c;
                    //获取n的next节点
                    Node<K,V> f = n.next;
                    //发生竞争,break
                    if (n != b.next)               // inconsistent read
                        break;
                    //如果n已经被删除
                    if ((v = n.value) == null) {   // n is deleted
                        n.helpDelete(b, f);
                        break;
                    }
                    //如果b已经被删除
                    if (b.value == null || v == n) // b is deleted
                        break;
                    //如果c>0,说明当前节点应该排在n的后面,所以从n后面继续比较
                    if ((c = cpr(cmp, key, n.key)) > 0) {
                        b = n;
                        n = f;
                        continue;
                    }
                    //如果键相等
                    if (c == 0) {
                        if (onlyIfAbsent || n.casValue(v, value)) {
                            @SuppressWarnings("unchecked") V vv = (V)v;
                            return vv;
                        }
                        break; // restart if lost race to replace value
                    }
                    // else c < 0; fall through
                }
                //如果n为null,说明b是链表的最后一个节点,
                //直接根据key,value,n创建一个新节点
                z = new Node<K,V>(key, value, n);
                //原子替换next域
                if (!b.casNext(n, z))
                    break;         // restart if lost race to append to b
                break outer;
            }
        }
        //生成随机数,随机提拔节点
        int rnd = ThreadLocalRandom.nextSecondarySeed();
        //判断是否需要增加level
        if ((rnd & 0x80000001) == 0) {// test highest and lowest bits
            int level = 1, max;
            while (((rnd >>>= 1) & 1) != 0)
                ++level;

            Index<K,V> idx = null;
            //保存头节点
            HeadIndex<K,V> h = head;
            //如果level小于跳表的层级
            if (level <= (max = h.level)) {
                //为节点生成对应的Index节点
                for (int i = 1; i <= level; ++i)
                    //依次赋值Index节点,并赋值节点的down域
                    idx = new Index<K,V>(z, idx, null);
            }
            else { // try to grow by one level
                level = max + 1; // hold in array and later pick the one to use
                //生成Index节点的数组
                @SuppressWarnings("unchecked")Index<K,V>[] idxs =
                        (Index<K,V>[])new Index<?,?>[level+1];
                //依次生成Index节点,并赋值down域
                for (int i = 1; i <= level; ++i)
                    idxs[i] = idx = new Index<K,V>(z, idx, null);
                for (;;) {
                    //保存头节点
                    h = head;
                    //保存旧层级
                    int oldLevel = h.level;
                    if (level <= oldLevel) // lost race to add level
                        break;
                    HeadIndex<K,V> newh = h;
                    //保存头节点对应的Node节点
                    Node<K,V> oldbase = h.node;
                    //为每一层生成一个头节点
                    for (int j = oldLevel+1; j <= level; ++j)
                        newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
                    //原子交换头节点
                    if (casHead(h, newh)) {
                        //h重新赋值为最高层的头节点
                        h = newh;
                        //idx赋值为旧层级的头节点,将level设置为之前的层级
                        idx = idxs[level = oldLevel];
                        break;
                    }
                }
            }
            // find insertion points and splice in
            //插入Index节点
            splice: for (int insertionLevel = level;;) {
                //保存新跳表的层级
                int j = h.level;
                for (Index<K,V> q = h, r = q.right, t = idx;;) {
                    //头节点或者idx节点为空
                    if (q == null || t == null)
                        //跳出循环
                        break splice;
                    //如果right节点不为空
                    if (r != null) {
                        //保存r的node
                        Node<K,V> n = r.node;
                        // compare before deletion check avoids needing recheck
                        int c = cpr(cmp, key, n.key);
                        if (n.value == null) {
                            if (!q.unlink(r))
                                break;
                            r = q.right;
                            continue;
                        }
                        if (c > 0) {
                            q = r;
                            r = r.right;
                            continue;
                        }
                    }

                    if (j == insertionLevel) {
                        //r节点插入q与t之间
                        if (!q.link(r, t))
                            break; // restart
                        //t节点的值为null,需要删除
                        if (t.node.value == null) {
                            findNode(key);
                            break splice;
                        }
                        if (--insertionLevel == 0)
                            break splice;
                    }

                    if (--j >= insertionLevel && j < level)
                        t = t.down;
                    q = q.down;
                    r = q.right;
                }
            }
        }
        return null;
    }

 

以上是关于ConcurrentSkipListMap源码---JDK1.8的主要内容,如果未能解决你的问题,请参考以下文章

JUC源码解析ConcurrentSkipListMap

源码角度了解ConcurrentSkipListMap

ConcurrentSkipListMap源码---JDK1.8

[JDK源码]-J.U.C-ConcurrentSkipListMap

集合-ConcurrentSkipListMap 源码解析

集合-ConcurrentSkipListMap 源码解析