码迷,mamicode.com
首页 > 其他好文 > 详细

ConcurrentSkipListMap源码---JDK1.8

时间:2017-12-06 18:05:22      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:point   and   rest   compare   保存   next   index   its   cal   

 

 

 

 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

标签:point   and   rest   compare   保存   next   index   its   cal   

原文地址:http://www.cnblogs.com/emoji1213/p/7993358.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!