JDK 8 ConcurrentSkipListMap 源码详解(详细注释版)

JDK 8 ConcurrentSkipListMap 源码详解(详细注释版)

1. 类定义和基本属性

public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
    implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
    
    // 序列化版本号
    private static final long serialVersionUID = -8627078645895051609L;

    /**
     * 比较器,用于定义键的排序规则
     * 如果为null,则使用键的自然排序
     */
    private final Comparator<? super K> comparator;

    /**
     * 跳表的头节点
     * 头节点不存储实际数据,作为跳表的起始点
     * 所有层级的头节点都指向同一个Node对象
     */
    private transient volatile HeadIndex<K,V> head;

    /**
     * 跳表的最大层级
     * 限制跳表的层级数量,避免过度分层
     */
    private static final int MAX_LEVEL = 31;

    /**
     * 随机数生成器,用于决定新节点的层级
     * 通过概率分布来确定节点层级,保证跳表的平衡性
     */
    private transient volatile ThreadLocalRandom random;

    /**
     * 删除操作的阈值
     * 当删除的节点数量超过此阈值时,触发清理操作
     */
    private transient volatile int baseLevel;

    /**
     * 节点内部类
     * 跳表的基本存储单元
     */
    static final class Node<K,V> {
        final K key;           // 节点的键
        volatile Object value;  // 节点的值(可能被标记为删除)
        volatile Node<K,V> next; // 指向下一个节点的引用

        /**
         * 构造方法
         * @param key 节点键
         * @param value 节点值
         * @param next 下一个节点
         */
        Node(K key, V value, Node<K,V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }

        /**
         * 构造方法(用于标记删除的节点)
         * @param key 节点键
         * @param next 下一个节点
         */
        Node(Node<K,V> next) {
            this.key = null;
            this.value = this; // 特殊标记,表示节点被删除
            this.next = next;
        }

        /**
         * 判断节点是否有效(未被删除)
         * @return 如果节点有效返回true,否则返回false
         */
        boolean isMarker() {
            return value == this;
        }

        /**
         * 判断节点是否base-level(最底层)
         * @param b 基准节点
         * @return 如果是base-level返回true,否则返回false
         */
        boolean isBaseHeader() {
            return value == BASE_HEADER;
        }

        /**
         * 尝试添加删除标记
         * @return 如果成功添加标记返回true,否则返回false
         */
        boolean casValue(Object cmp, Object val) {
            return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
        }

        /**
         * CAS操作更新next指针
         * @param cmp 预期的当前值
         * @param val 新值
         * @return 如果更新成功返回true,否则返回false
         */
        boolean casNext(Node<K,V> cmp, Node<K,V> val) {
            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
        }

        // Unsafe操作相关
        private static final sun.misc.Unsafe UNSAFE;
        private static final long valueOffset;
        private static final long nextOffset;

        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class<?> k = Node.class;
                valueOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("value"));
                nextOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("next"));
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }

    /**
     * 索引节点内部类
     * 用于构建跳表的多层索引结构
     */
    static class Index<K,V> {
        final Node<K,V> node;      // 关联的数据节点
        final Index<K,V> down;     // 指向下层索引节点
        volatile Index<K,V> right; // 指向右侧索引节点

        /**
         * 构造方法
         * @param node 关联的数据节点
         * @param down 下层索引节点
         * @param right 右侧索引节点
         */
        Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
            this.node = node;
            this.down = down;
            this.right = right;
        }

        /**
         * CAS操作更新right指针
         * @param cmp 预期的当前值
         * @param val 新值
         * @return 如果更新成功返回true,否则返回false
         */
        final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
            return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
        }

        /**
         * 判断节点是否有效
         * @return 如果节点有效返回true,否则返回false
         */
        final boolean indexesDeletedNode() {
            return node.value == null;
        }

        /**
         * 链接新的右侧节点
         * @param succ 成功的节点
         * @param newSucc 新的成功节点
         * @return 如果链接成功返回true,否则返回false
         */
        final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
            Node<K,V> x = node;
            newSucc.right = succ;
            return x.value != null && casRight(succ, newSucc);
        }

        /**
         * 取消链接右侧节点
         * @param succ 成功的节点
         * @return 如果取消链接成功返回true,否则返回false
         */
        final boolean unlink(Index<K,V> succ) {
            return node.value != null && casRight(succ, succ.right);
        }

        // Unsafe操作相关
        private static final sun.misc.Unsafe UNSAFE;
        private static final long rightOffset;

        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class<?> k = Index.class;
                rightOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("right"));
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }

    /**
     * 头索引节点内部类
     * 跳表各层的头节点
     */
    static final class HeadIndex<K,V> extends Index<K,V> {
        final int level; // 层级

        HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
            super(node, down, right);
            this.level = level;
        }
    }

    /**
     * 基础头节点的特殊标记值
     */
    static final Object BASE_HEADER = new Object();

2. 构造方法(详细注释)

    /**
     * 默认构造方法
     * 创建一个使用键自然排序的ConcurrentSkipListMap
     * 
     * 初始化过程:
     * 1. 设置比较器为null(使用自然排序)
     * 2. 创建初始的跳表结构
     * 3. 初始化头节点和随机数生成器
     */
    public ConcurrentSkipListMap() {
        this.comparator = null; // 使用自然排序
        initialize(); // 初始化跳表结构
    }

    /**
     * 使用指定比较器的构造方法
     * @param comparator 用于排序的比较器
     * 
     * 比较器说明:
     * - 如果comparator为null,使用自然排序
     * - 否则使用指定的比较器进行排序
     * - 比较器必须保持一致性
     */
    public ConcurrentSkipListMap(Comparator<? super K> comparator) {
        this.comparator = comparator; // 设置比较器
        initialize(); // 初始化跳表结构
    }

    /**
     * 从SortedMap构造ConcurrentSkipListMap
     * @param m 包含初始数据的SortedMap
     * 
     * 构造过程:
     * 1. 使用m的比较器
     * 2. 初始化跳表结构
     * 3. 逐个添加m中的元素
     */
    public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
        this.comparator = m.comparator(); // 使用相同的比较器
        initialize(); // 初始化跳表结构
        buildFromSorted(m); // 从有序数据构建
    }

    /**
     * 从Map构造ConcurrentSkipListMap
     * @param m 包含初始数据的Map
     * 
     * 构造过程:
     * 1. 使用自然排序
     * 2. 初始化跳表结构
     * 3. 逐个添加m中的元素
     */
    public ConcurrentSkipListMap(Map<K, ? extends V> m) {
        this.comparator = null; // 使用自然排序
        initialize(); // 初始化跳表结构
        putAll(m); // 添加所有元素
    }

    /**
     * 初始化跳表结构
     * 创建初始的头节点和相关组件
     */
    private void initialize() {
        keySet = null;
        entrySet = null;
        values = null;
        descendingKeySet = null;
        random = new ThreadLocalRandom(); // 初始化随机数生成器
        baseLevel = 1;
        // 创建初始节点和头索引
        Node<K,V> baseHead = new Node<K,V>(null, BASE_HEADER, null);
        head = new HeadIndex<K,V>(baseHead, null, null, 1);
    }

    /**
     * 从有序数据构建跳表
     * @param map 包含有序数据的Map
     */
    private void buildFromSorted(SortedMap<K, ? extends V> map) {
        // 逐个添加元素
        for (Map.Entry<K, ? extends V> e : map.entrySet())
            put(e.getKey(), e.getValue());
    }

3. 核心查找方法(详细注释)

    /**
     * 获取指定键对应的值
     * @param key 要查找的键
     * @return 键对应的值,如果键不存在返回null
     * 
     * 查找过程:
     * 1. 从最高层开始,向右查找
     * 2. 如果右侧节点的键大于目标键,向下一层
     * 3. 如果找到匹配的键,返回对应的值
     * 4. 如果到达最底层仍未找到,返回null
     * 
     * 时间复杂度:平均O(log n),最坏O(n)
     */
    public V get(Object key) {
        return doGet(key);
    }

    /**
     * 实际的获取操作
     * @param key 要查找的键
     * @return 键对应的值,如果键不存在返回null
     */
    private V doGet(Object key) {
        if (key == null)
            throw new NullPointerException(); // 不允许null键
        Comparator<? super K> cmp = comparator;
        outer: for (;;) {
            // 从头节点开始查找
            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                Object v; int c;
                if (n == null)
                    break outer; // 到达链表末尾
                Node<K,V> f = n.next;
                if (n != b.next)               // inconsistent read
                    break;
                if ((v = n.value) == null) {   // n is deleted
                    n.helpDelete(b, f);
                    break;
                }
                if (b.value == null || v == n) // b is deleted
                    break;
                if ((c = cpr(cmp, key, n.key)) == 0) {
                    @SuppressWarnings("unchecked") V vv = (V)v;
                    return vv;
                }
                if (c < 0)
                    break outer;
                b = n;
                n = f;
            }
        }
        return null;
    }

    /**
     * 查找指定键的前驱节点
     * @param key 要查找的键
     * @param cmp 比较器
     * @return 前驱节点
     */
    private Node<K,V> findPredecessor(Object key, Comparator<? super K> cmp) {
        if (key == null)
            throw new NullPointerException(); // 不允许null键
        for (;;) {
            // 从最高层开始查找
            for (Index<K,V> q = head, r = q.right, d;;) {
                if (r != null) {
                    Node<K,V> n = r.node;
                    K k = n.key;
                    if (n.value == null) {
                        if (!q.unlink(r))
                            break;           // restart
                        r = q.right;         // re-read r
                        continue;
                    }
                    if (cpr(cmp, key, k) > 0) {
                        q = r;
                        r = r.right;
                        continue;
                    }
                }
                if ((d = q.down) != null) {
                    q = d;
                    r = d.right;
                } else
                    return q.node;
            }
        }
    }

    /**
     * 比较两个键
     * @param c 比较器
     * @param x 第一个键
     * @param y 第二个键
     * @return 比较结果
     */
    private static int cpr(Comparator c, Object x, Object y) {
        return (c != null) ? c.compare(x, y) : ((Comparable)x).compareTo(y);
    }

4. 核心插入方法(详细注释)

    /**
     * 插入键值对
     * @param key 键
     * @param value 值
     * @return 如果是更新操作返回旧值,如果是插入操作返回null
     * 
     * 插入过程:
     * 1. 查找插入位置
     * 2. 如果键已存在,更新值
     * 3. 如果键不存在,创建新节点
     * 4. 随机确定新节点的层级
     * 5. 更新索引结构
     * 
     * 时间复杂度:平均O(log n)
     */
    public V put(K key, V value) {
        if (value == null)
            throw new NullPointerException(); // 不允许null值
        return doPut(key, value, false);
    }

    /**
     * 如果键不存在则插入
     * @param key 键
     * @param value 值
     * @return 如果插入成功返回null,如果键已存在返回旧值
     */
    public V putIfAbsent(K key, V value) {
        if (value == null)
            throw new NullPointerException(); // 不允许null值
        return doPut(key, value, true);
    }

    /**
     * 实际的插入操作
     * @param key 键
     * @param value 值
     * @param onlyIfAbsent 是否只在键不存在时插入
     * @return 如果是更新操作返回旧值,如果是插入操作返回null
     */
    private V doPut(K key, V value, boolean onlyIfAbsent) {
        Node<K,V> z;             // 新增节点
        if (key == null)
            throw new NullPointerException();
        Comparator<? super K> cmp = comparator;
        outer: for (;;) {
            // 查找插入位置
            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                if (n != null) {
                    Object v; int c;
                    Node<K,V> f = n.next;
                    if (n != b.next)               // inconsistent read
                        break;
                    if ((v = n.value) == null) {   // n is deleted
                        n.helpDelete(b, f);
                        break;
                    }
                    if (b.value == null || v == n) // b is deleted
                        break;
                    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
                }

                z = new Node<K,V>(key, value, n);
                if (!b.casNext(n, z))
                    break;         // restart if lost race to append to b
                break outer;
            }
        }

        // 随机确定层级并插入索引
        int rnd = random.nextInt();
        if ((rnd & 0x80000001) == 0) { // test highest and lowest bits
            int level = 1, max;
            while (((rnd >>>= 1) & 1) != 0)
                ++level;
            if (level > (max = head.level)) {
                if (max >= MAX_LEVEL)
                    level = MAX_LEVEL;
                else {
                    HeadIndex<K,V> newHead = new HeadIndex<K,V>(z, null, null, level);
                    for (;;) {
                        HeadIndex<K,V> oldHead = head;
                        if (level <= oldHead.level || !casHead(oldHead, newHead))
                            break;
                    }
                }
            }
            if (level > 0)
                insertIndex(z, level);
        }
        return null;
    }

    /**
     * 插入索引节点
     * @param z 数据节点
     * @param level 层级
     */
    private void insertIndex(Node<K,V> z, int level) {
        HeadIndex<K,V> h = head;
        int max = h.level;

        if (level <= max) {
            Index<K,V> idx = null;
            for (int i = 1; i <= level; ++i)
                idx = new Index<K,V>(z, idx, null);
            addIndex(idx, h, level);
        } else { // Add a new level
            // 此处省略层级扩展的详细实现
        }
    }

    /**
     * 添加索引节点
     * @param idx 索引节点
     * @param h 头节点
     * @param indexLevel 索引层级
     */
    private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
        // 从指定层级开始,逐层添加索引
        int insertionLevel = indexLevel;
        Index<K,V> q = h;
        Index<K,V> r = h.right;
        for (int j = h.level; j >= insertionLevel; --j) {
            for (;;) {
                Index<K,V> rn = r == null ? null : r.right;
                if (j < insertionLevel) {
                    if (j + 1 < insertionLevel) {
                        // 插入到下一层
                        Index<K,V> down = idx.down;
                        Index<K,V> nd = new Index<K,V>(idx.node, down, null);
                        idx.right = nd;
                        idx = nd;
                    }
                    break;
                }
                if (rn != null && rn.node.key != null) {
                    int c = cpr(comparator, idx.node.key, rn.node.key);
                    if (c > 0) {
                        q = r;
                        r = rn;
                        continue;
                    }
                }
                Index<K,V> rd = r;
                idx.right = rd;
                if (q.casRight(r, idx))
                    break;
                r = q.right;
            }
            if (--insertionLevel == 0)
                break;
            Index<K,V> down = idx.down;
            Index<K,V> nd = new Index<K,V>(idx.node, down, null);
            idx.right = nd;
            idx = nd;
            q = q.down;
            r = q.right;
        }
    }

    /**
     * CAS更新头节点
     * @param cmp 预期的当前值
     * @param val 新值
     * @return 如果更新成功返回true,否则返回false
     */
    private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
    }

5. 核心删除方法(详细注释)

    /**
     * 删除指定键的映射关系
     * @param key 要删除的键
     * @return 被删除的值,如果键不存在返回null
     * 
     * 删除过程:
     * 1. 查找要删除的节点
     * 2. 标记节点为删除状态
     * 3. 物理删除节点
     * 4. 更新索引结构
     * 
     * 时间复杂度:平均O(log n)
     */
    public V remove(Object key) {
        return doRemove(key, null);
    }

    /**
     * 条件删除
     * @param key 要删除的键
     * @param value 期望的值
     * @return 如果删除成功返回true,否则返回false
     */
    public boolean remove(Object key, Object value) {
        if (key == null)
            throw new NullPointerException();
        if (value == null)
            return false;
        return doRemove(key, value) != null;
    }

    /**
     * 实际的删除操作
     * @param key 要删除的键
     * @param value 期望的值(null表示不检查值)
     * @return 被删除的值,如果删除失败返回null
     */
    final V doRemove(Object key, Object value) {
        if (key == null)
            throw new NullPointerException();
        Comparator<? super K> cmp = comparator;
        outer: for (;;) {
            // 查找要删除的节点
            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                Object v; int c;
                if (n == null)
                    break outer;
                Node<K,V> f = n.next;
                if (n != b.next)                    // inconsistent read
                    break;
                if ((v = n.value) == null) {        // n is deleted
                    n.helpDelete(b, f);
                    break;
                }
                if (b.value == null || v == n)      // b is deleted
                    break;
                if ((c = cpr(cmp, key, n.key)) < 0)
                    break outer;
                if (c > 0) {
                    b = n;
                    n = f;
                    continue;
                }
                if (value != null && !value.equals(v))
                    break outer;
                if (!n.casValue(v, null))
                    break;
                if (!n.appendMarker(f) || !b.casNext(n, f))
                    findNode(key);                  // retry via findNode
                else {
                    findPredecessor(key, cmp);      // clean index
                    if (head.right == null)
                        tryReduceLevel();
                }
                @SuppressWarnings("unchecked") V vv = (V)v;
                return vv;
            }
        }
        return null;
    }

    /**
     * 帮助删除节点
     * @param b 前驱节点
     * @param f 后继节点
     */
    void helpDelete(Node<K,V> b, Node<K,V> f) {
        if (f == next && this == b.next) {
            if (f == null || f.value != f) // not already marked
                casNext(f, new Node<K,V>(f));
            else
                b.casNext(this, f.next);
        }
    }

    /**
     * 追加删除标记
     * @param next 后继节点
     * @return 如果成功追加标记返回true,否则返回false
     */
    boolean appendMarker(Node<K,V> next) {
        return casNext(next, new Node<K,V>(next));
    }

    /**
     * 尝试减少层级
     * 当头节点的右侧为空时调用
     */
    private void tryReduceLevel() {
        HeadIndex<K,V> h = head;
        HeadIndex<K,V> d;
        HeadIndex<K,V> e;
        if (h.level > 3 &&
            (d = (HeadIndex<K,V>)h.down) != null &&
            (e = (HeadIndex<K,V>)d.down) != null &&
            e.right == null &&
            d.right == null &&
            h.right == null &&
            casHead(h, d) && // try to set
            h.right != null) // recheck
            casHead(d, h);   // try to backout
    }

6. 导航方法(详细注释)

    /**
     * 返回小于等于指定键的最大键
     * @param key 指定键
     * @return 小于等于key的最大键,如果不存在返回null
     */
    public K floorKey(K key) {
        return findNear(key, LT|EQ, comparator);
    }

    /**
     * 返回大于等于指定键的最小键
     * @param key 指定键
     * @return 大于等于key的最小键,如果不存在返回null
     */
    public K ceilingKey(K key) {
        return findNear(key, GT|EQ, comparator);
    }

    /**
     * 返回小于指定键的最大键
     * @param key 指定键
     * @return 小于key的最大键,如果不存在返回null
     */
    public K lowerKey(K key) {
        return findNear(key, LT, comparator);
    }

    /**
     * 返回大于指定键的最小键
     * @param key 指定键
     * @return 大于key的最小键,如果不存在返回null
     */
    public K higherKey(K key) {
        return findNear(key, GT, comparator);
    }

    /**
     * 查找最近的节点
     * @param key 目标键
     * @param rel 关系标志
     * @param cmp 比较器
     * @return 找到的键,如果不存在返回null
     */
    private K findNear(K key, int rel, Comparator<? super K> cmp) {
        if (key == null)
            throw new NullPointerException();
        for (;;) {
            // 从头节点开始查找
            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                Object v; int c;
                if (n == null) {
                    if ((rel & LT) == 0)
                        break;
                    for (Node<K,V> p = b; p != null; p = p.prev) {
                        if (p.value != null && p.value != p) {
                            @SuppressWarnings("unchecked") K kk = (K)p.key;
                            return kk;
                        }
                    }
                    break;
                }
                Node<K,V> f = n.next;
                if (n != b.next)               // inconsistent read
                    break;
                if ((v = n.value) == null) {   // n is deleted
                    n.helpDelete(b, f);
                    break;
                }
                if (b.value == null || v == n) // b is deleted
                    break;
                if ((c = cpr(cmp, key, n.key)) == 0) {
                    if ((rel & EQ) != 0) {
                        @SuppressWarnings("unchecked") K kk = (K)n.key;
                        return kk;
                    }
                    if ((rel & LT) != 0) {
                        for (Node<K,V> p = b; p != null; p = p.prev) {
                            if (p.value != null && p.value != p) {
                                @SuppressWarnings("unchecked") K kk = (K)p.key;
                                return kk;
                            }
                        }
                        break;
                    }
                    n = f;
                    continue;
                }
                if (c < 0) {
                    if ((rel & LT) == 0)
                        break;
                    for (Node<K,V> p = b; p != null; p = p.prev) {
                        if (p.value != null && p.value != p) {
                            @SuppressWarnings("unchecked") K kk = (K)p.key;
                            return kk;
                        }
                    }
                    break;
                }
                b = n;
                n = f;
            }
        }
        return null;
    }

    // 关系标志常量
    private static final int EQ = 1; // 相等
    private static final int LT = 2; // 小于
    private static final int GT = 4; // 大于

7. 范围操作方法(详细注释)

    /**
     * 返回此映射的部分视图,键的范围从fromKey到toKey
     * @param fromKey 起始键(包含)
     * @param fromInclusive 是否包含起始键
     * @param toKey 结束键(不包含)
     * @param toInclusive 是否包含结束键
     * @return 指定范围的子映射
     */
    public ConcurrentNavigableMap<K,V> subMap(K fromKey,
                                              boolean fromInclusive,
                                              K toKey,
                                              boolean toInclusive) {
        if (fromKey == null || toKey == null)
            throw new NullPointerException();
        return new SubMap<K,V>
            (this, fromKey, fromInclusive, toKey, toInclusive, false);
    }

    /**
     * 返回此映射的部分视图,键小于toKey
     * @param toKey 结束键
     * @param inclusive 是否包含结束键
     * @return 头部映射
     */
    public ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive) {
        if (toKey == null)
            throw new NullPointerException();
        return new SubMap<K,V>(this, null, false, toKey, inclusive, false);
    }

    /**
     * 返回此映射的部分视图,键大于等于fromKey
     * @param fromKey 起始键
     * @param inclusive 是否包含起始键
     * @return 尾部映射
     */
    public ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
        if (fromKey == null)
            throw new NullPointerException();
        return new SubMap<K,V>(this, fromKey, inclusive, null, false, false);
    }

    /**
     * SubMap内部类,实现范围映射
     */
    static final class SubMap<K,V> extends AbstractMap<K,V>
        implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
        // 省略具体实现细节
    }

8. 迭代器实现(详细注释)

    /**
     * 返回键的可导航集合
     * @return 键集合
     */
    public NavigableSet<K> navigableKeySet() {
        KeySet<K> ks = keySet;
        return (ks != null) ? ks : (keySet = new KeySet<K>(this));
    }

    /**
     * 键集合内部类
     */
    static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
        private final ConcurrentNavigableMap<E,?> m;

        KeySet(ConcurrentNavigableMap<E,?> map) { m = map; }

        public int size() { return m.size(); }
        public boolean isEmpty() { return m.isEmpty(); }
        public boolean contains(Object o) { return m.containsKey(o); }
        public boolean remove(Object o) { return m.remove(o) != null; }
        public void clear() { m.clear(); }

        /**
         * 返回迭代器
         * @return 键迭代器
         */
        public Iterator<E> iterator() {
            if (m instanceof ConcurrentSkipListMap)
                return ((ConcurrentSkipListMap<E,?>)m).keyIterator();
            else
                return ((ConcurrentSkipListMap.SubMap<E,?>)m).keyIterator();
        }

        /**
         * 返回降序迭代器
         * @return 降序键迭代器
         */
        public Iterator<E> descendingIterator() {
            return descendingIterator();
        }
    }

    /**
     * 返回键迭代器
     * @return 键迭代器
     */
    Iterator<K> keyIterator() {
        return new KeyIterator();
    }

    /**
     * 键迭代器内部类
     */
    final class KeyIterator extends Iter<K> {
        public K next() {
            Node<K,V> n = next;
            if (n == null)
                throw new NoSuchElementException();
            K x = n.key;
            last = n;
            advance();
            return x;
        }
    }

    /**
     * 迭代器基类
     */
    abstract class Iter<T> implements Iterator<T> {
        /** the last node returned by next() */
        Node<K,V> last;

        /** the next node to return from next(); */
        Node<K,V> next;

        /** next node on predecessor's level */
        Node<K,V> nextPrec;

        /** predecessor of last returned node */
        Node<K,V> prev;

        /** predecessor of next node */
        Node<K,V> prevPrec;

        /** estimated number of elements */
        long est;

        /** true if last() called */
        boolean lastRet;

        /** true if descending */
        boolean descending;

        Iter() {
            advance();
        }

        /**
         * Advance next to higher entry.
         * Precondition: next != null.
         */
        final void advance() {
            Node<K,V> n = next;
            if (n == null) {
                next = null;
                est = 0;
            } else {
                Node<K,V> f = n.next;
                for (;;) {
                    if (f == null) {
                        next = null;
                        est = 0;
                        break;
                    }
                    Object v = f.value;
                    if (v != null && v != f) {
                        next = f;
                        est--;
                        break;
                    }
                    f = f.next;
                }
            }
        }

        public final boolean hasNext() {
            return next != null;
        }

        /** Returns current node, advancing next. */
        final Node<K,V> nextNode() {
            Node<K,V> n = next;
            if (n == null)
                throw new NoSuchElementException();
            last = n;
            advance();
            return n;
        }

        public void remove() {
            Node<K,V> l = last;
            if (l == null)
                throw new IllegalStateException();
            m.remove(l.key);
            last = null;
        }
    }

9. ConcurrentSkipListMap 的特点分析

核心设计理念:

/**
 * ConcurrentSkipListMap的核心设计思想:
 * 
 * 1. 跳表数据结构:
 *    - 多层链表结构,提供快速查找
 *    - 每层都是一个有序链表
 *    - 上层节点稀疏,下层节点密集
 *    - 通过随机化保持结构平衡
 * 
 * 2. 无锁并发控制:
 *    - 使用CAS操作实现无锁化
 *    - 减少锁竞争,提高并发性能
 *    - 支持高并发读写操作
 * 
 * 3. 有序性保证:
 *    - 键按照自然顺序或比较器排序
 *    - 支持范围查询和导航操作
 *    - 提供有序的迭代器
 * 
 * 4. 原子性操作:
 *    - 插入、删除、查找操作都是原子的
 *    - 保证数据一致性
 *    - 支持复合操作
 * 
 * 5. 内存管理:
 *    - 及时清理删除的节点
 *    - 避免内存泄漏
 *    - 支持GC友好设计
 * 
 * 适用场景:
 * - 需要有序映射的高并发场景
 * - 频繁进行范围查询的场景
 * - 需要导航操作的场景
 * - 要求无锁并发的场景
 */

性能特征分析:

/**
 * ConcurrentSkipListMap的性能特征:
 * 
 * 时间复杂度:
 * - get(key): O(log n) 平均情况
 * - put(key, value): O(log n) 平均情况
 * - remove(key): O(log n) 平均情况
 * - containsKey(key): O(log n) 平均情况
 * - firstKey()/lastKey(): O(log n) 平均情况
 * - subMap(): O(log n) 创建视图
 * 
 * 空间复杂度:
 * - O(n) 基本存储空间
 * - 额外的索引节点开销
 * - 平均每个节点约2个指针的额外开销
 * 
 * 并发特性:
 * - 无锁设计,减少锁竞争
 * - 支持高并发读写
 * - 弱一致性:读操作可能看不到最新的写操作
 * - 不会抛出ConcurrentModificationException
 * 
 * 内存使用:
 * - 动态分配,按需扩展
 * - 索引节点占用额外内存
 * - 及时GC,避免内存泄漏
 * 
 * 适用性:
 * - 读操作频繁:性能优秀
 * - 写操作频繁:性能良好
 * - 范围查询:性能优秀
 * - 有序遍历:性能优秀
 */

10. 使用示例和最佳实践

/**
 * 使用示例:
 * 
 * // 基本使用
 * ConcurrentSkipListMap<String, Integer> map = new ConcurrentSkipListMap<>();
 * 
 * // 添加元素
 * map.put("apple", 1);
 * map.put("banana", 2);
 * map.put("cherry", 3);
 * 
 * // 查找元素
 * Integer value = map.get("apple");
 * System.out.println("Value: " + value);
 * 
 * // 范围操作
 * ConcurrentNavigableMap<String, Integer> subMap = 
 *     map.subMap("apple", true, "cherry", true);
 * System.out.println("SubMap: " + subMap);
 * 
 * // 导航操作
 * String firstKey = map.firstKey();
 * String lastKey = map.lastKey();
 * String lowerKey = map.lowerKey("banana");
 * String higherKey = map.higherKey("banana");
 * 
 * // 并发使用示例
 * ExecutorService executor = Executors.newFixedThreadPool(10);
 * 
 * // 并发写入
 * for (int i = 0; i < 10; i++) {
 *     final int threadId = i;
 *     executor.submit(() -> {
 *         for (int j = 0; j < 1000; j++) {
 *             map.put("thread" + threadId + "_item" + j, j);
 *         }
 *     });
 * }
 * 
 * // 并发读取
 * for (int i = 0; i < 10; i++) {
 *     executor.submit(() -> {
 *         for (int j = 0; j < 1000; j++) {
 *             Integer value = map.get("someKey");
 *             // 处理值
 *         }
 *     });
 * }
 * 
 * 最佳实践:
 * 
 * 1. 合理选择键类型:
 *    // 键应该实现Comparable接口或提供Comparator
 *    ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
 *    
 *    // 或者使用自定义比较器
 *    Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
 *    ConcurrentSkipListMap<String, Integer> map2 = 
 *        new ConcurrentSkipListMap<>(comparator);
 * 
 * 2. 避免频繁的范围操作:
 *    // 范围操作虽然高效,但仍需谨慎使用
 *    NavigableMap<String, Integer> range = 
 *        map.headMap("m", false); // 所有小于"m"的键
 *    
 *    // 遍历范围
 *    for (Map.Entry<String, Integer> entry : range.entrySet()) {
 *        System.out.println(entry.getKey() + ": " + entry.getValue());
 *    }
 * 
 * 3. 正确处理null值:
 *    // 不允许null键和null值
 *    try {
 *        map.put(null, "value"); // 抛出NullPointerException
 *    } catch (NullPointerException e) {
 *        System.out.println("Null keys are not allowed");
 *    }
 *    
 *    try {
 *        map.put("key", null); // 抛出NullPointerException
 *    } catch (NullPointerException e) {
 *        System.out.println("Null values are not allowed");
 *    }
 * 
 * 4. 使用原子操作:
 *    // 使用原子操作避免竞态条件
 *    map.putIfAbsent("key", "value");
 *    map.replace("key", "oldValue", "newValue");
 *    map.remove("key", "value");
 * 
 * 5. 监控性能:
 *    // 监控映射大小
 *    int size = map.size();
 *    System.out.println("Map size: " + size);
 *    
 *    // 在高并发环境下,size()可能是估算值
 * 
 * 6. 合理使用视图:
 *    // 创建子映射视图
 *    ConcurrentNavigableMap<String, Integer> subMap = 
 *        map.subMap("a", true, "z", false);
 *    
 *    // 视图操作会反映到原映射中
 *    subMap.put("newKey", 100);
 *    System.out.println(map.containsKey("newKey")); // true
 * 
 * 7. 注意内存使用:
 *    // 大量数据时注意内存使用
 *    if (map.size() > 100000) {
 *        System.out.println("Large map size, consider memory usage");
 *    }
 * 
 * 8. 正确使用迭代器:
 *    // 迭代器是弱一致性的
 *    Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
 *    while (it.hasNext()) {
 *        Map.Entry<String, Integer> entry = it.next();
 *        // 处理条目
 *        // 注意:迭代过程中可能看不到最新的修改
 *    }
 * 
 * 9. 异常处理:
 *    // 处理可能的并发异常
 *    try {
 *        String value = map.get("key");
 *        // 处理值
 *    } catch (Exception e) {
 *        System.out.println("Error during map operation: " + e.getMessage());
 *    }
 * 
 * 10. 性能调优:
 *    // 对于读多写少的场景,性能优秀
 *    // 对于写多读少的场景,考虑其他数据结构
 *    // 频繁的范围查询场景,ConcurrentSkipListMap是很好的选择
 */

11. 与其他并发映射的比较

/**
 * ConcurrentSkipListMap vs ConcurrentHashMap vs ConcurrentNavigableMap:
 * 
 * ConcurrentSkipListMap:
 * - 基于跳表实现
 * - 保持键的有序性
 * - 支持导航操作
 * - 无锁设计,CAS操作
 * - 适合有序访问场景
 * - 内存开销相对较大
 * 
 * ConcurrentHashMap:
 * - 基于哈希表实现
 * - 不保持键的有序性
 * - 不支持导航操作
 * - 分段锁或CAS+synchronized
 * - 适合高性能哈希访问
 * - 内存开销相对较小
 * 
 * TreeMap (非并发):
 * - 基于红黑树实现
 * - 保持键的有序性
 * - 支持导航操作
 * - 需要外部同步
 * - 单线程性能优秀
 * 
 * 选择建议:
 * - 需要有序映射且高并发:ConcurrentSkipListMap
 * - 高性能哈希访问:ConcurrentHashMap
 * - 单线程有序访问:TreeMap
 * - 需要范围查询:ConcurrentSkipListMap
 * 
 * 性能对比:
 * - 读操作:ConcurrentHashMap > ConcurrentSkipListMap > TreeMap
 * - 写操作:ConcurrentHashMap ≈ ConcurrentSkipListMap > TreeMap
 * - 范围查询:ConcurrentSkipListMap > TreeMap > ConcurrentHashMap
 * - 内存使用:TreeMap < ConcurrentHashMap < ConcurrentSkipListMap
 * - 并发性:ConcurrentSkipListMap ≈ ConcurrentHashMap > TreeMap
 */

12. 总结

ConcurrentSkipListMap 的核心特性:

  1. 跳表实现

    • 多层有序链表结构
    • 平均O(log n)的查找性能
    • 通过随机化保持平衡
  2. 无锁并发

    • 使用CAS操作实现无锁化
    • 减少锁竞争,提高并发性能
    • 支持高并发读写操作
  3. 有序性保证

    • 键按照自然顺序或比较器排序
    • 支持范围查询和导航操作
    • 提供有序的迭代器
  4. 原子性操作

    • 插入、删除、查找操作都是原子的
    • 保证数据一致性
    • 支持复合操作
  5. 线程安全

    • 所有操作都是线程安全的
    • 不需要外部同步
    • 支持多个并发访问

适用场景:

  • 需要有序映射的高并发场景
  • 频繁进行范围查询的场景
  • 需要导航操作的场景
  • 要求无锁并发的场景
  • 需要保持键排序的应用

注意事项:

  • 不允许存储null键和null值
  • 内存开销比HashMap大
  • 迭代器是弱一致性的
  • size()方法返回的是估算值
  • 比较器必须保持一致性

性能优化建议:

  1. 合理选择键类型和比较器
  2. 避免频繁的范围操作
  3. 正确使用原子操作方法
  4. 监控内存使用情况
  5. 根据访问模式选择合适的数据结构
  6. 在高并发环境下注意性能调优
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值