一、前言

  最近在做项目的同时也在修复之前项目的一些Bug,所以忙得没有时间看源代码,今天都完成得差不多了,所以又开始源码分析之路,也着笔记录下ConcurrentSkipListMap的源码的分析过程。

二、ConcurrentSkipListMap数据结构

  抓住了数据结构,对于理解整个ConcurrentSkipListMap有很重要的作用,其实,通过源码可知其数据结构如下。

【JUC】JDK1.8源码分析之ConcurrentSkipListMap(二)

  说明:可以看到ConcurrentSkipListMap的数据结构使用的是跳表,每一个HeadIndex、Index结点都会包含一个对Node的引用,同一垂直方向上的Index、HeadIndex结点都包含了最底层的Node结点的引用。并且层级越高,该层级的结点(HeadIndex和Index)数越少。Node结点之间使用单链表结构。

三、ConcurrentSkipListMap源码分析

  3.1 类的继承关系 

public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
    implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {}

  说明:ConcurrentSkipListMap继承了AbstractMap抽象类,实现了ConcurrentNavigableMap接口,该接口定义了获取某一部分集合的操作。实现了Cloneable接口,表示允许克隆。实现了Serializable接口,表示可被序列化。

  3.2 类的内部类

  ConcurrentSkipListMap包含了很多内部类,内部类的框架图如下:

【JUC】JDK1.8源码分析之ConcurrentSkipListMap(二)

  说明:其中,最为重要的类包括Index、HeadIndex、Node三个类。下面对这三个类进行逐一讲解,其他的类,读者有兴趣可以自行分析。

  ① Index类

  1. 类的属性 

    static class Index<K,V> {
        final Node<K,V> node;
        final Index<K,V> down;
        volatile Index<K,V> right;
        
        // Unsafe mechanics
        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);
            }
        }
    }

  说明:可以看到,Index结点包括一个Node结点的引用,都是包含down域和right域,即对应数据结构中的Index结点。并且借助了反射来原子性的修改right域。

  2. 类的构造函数   

 /**
         * Creates index node with given values.
         */
        Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
            this.node = node;
            this.down = down;
            this.right = right;
        }
View Code

相关文章: