JUC—ConcurrentSkipListSet源码深度解析

  基于JDK1.8详细介绍了ConcurrentSkipListSet的底层源码实现,实际上就是对ConcurrentSkipListMap的包装!

1 ConcurrentSkipListSet的概述

public class ConcurrentSkipListSet < E >
  extends AbstractSet < E >
  implements NavigableSet< E >, Cloneable, Serializable

  ConcurrentSkipListSet也是JDK1.6加入的集合类,顾名思义,它是一种Set类型,类似于TreeSet,支持排序并且没有重复元素。但是ConcurrentSkipListSet是线程安全的,并且TreeSet是通过TreeMap实现的,而ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的。
  ConcurrentSkipListSet相当于对ConcurrentSkipListMap的包装,ConcurrentSkipListSet的内部具有一个ConcurrentSkipListMap的实例,通过ConcurrentSkipListMap的方法来完成ConcurrentSkipListSet的功能!
  ConcurrentSkipListSet不允许 null 元素!
  ConcurrentSkipListSet实现了Cloneable和Serializable接口,因此支持克隆和序列化!
  看懂了ConcurrentSkipListMap的源码,你就看懂了ConcurrentSkipListSet的源码:JUC—三万字的ConcurrentSkipListMap源码深度解析
在这里插入图片描述

2 ConcurrentSkipListSet的实现

2.1 基本结构

  在初始化ConcurrentSkipListSet对象时,实际上内部初始化了个ConcurrentSkipListMap对象,并由字段m引用,所有API方法均委托ConcurrentSkipListMap对象完成,这类似于装饰设计模式!所以其实ConcurrentSkipListSet就是一种跳表类型的数据结构,其平均增删改查的时间复杂度均为O(logn)。

/**
 * 内部持有的ConcurrentSkipListMap对象的引用,将会在构造器中初始化!
 */
private final ConcurrentNavigableMap<E, Object> m;

/**
 * 构造一个新的Set集合,该集合将按照键的自然顺序(Comparable.compareTo)进行排序。
 */
public ConcurrentSkipListSet() {
    //初始化一个ConcurrentSkipListMap对象
    m = new ConcurrentSkipListMap<E, Object>();
}

/**
 * 构造一个新的Set集合,该集合按照指定的比较器comparator进行排序。
 *
 * @param comparator 指定比较器,Comparator接口的实现,如果为null那么还是按照自然顺序进行排序
 */
public ConcurrentSkipListSet(Comparator<? super E> comparator) {
    //调用对应的ConcurrentSkipListMap的构造器
    m = new ConcurrentSkipListMap<E, Object>(comparator);
}

/**
 * 构造一个新Set集合,该集合所包含的元素与指定集合包含的元素相同,并按照键的自然顺序进行排序。
 *
 * @param c 指定集合
 * @throws ClassCastException   如果元素不是Comparable接口的实现 或者 无法进行比较
 * @throws NullPointerException 如果指定集合 或者 它的任意元素 为null
 */
public ConcurrentSkipListSet(Collection<? extends E> c) {
    //初始化一个ConcurrentSkipListMap对象
    m = new ConcurrentSkipListMap<E, Object>();
    //调用addAll方法
    addAll(c);
}

/**
 * 构造一个新Set集合,该集合所包含的元素与指定的有序集合包含的元素相同,使用的排序顺序也相同。
 *
 * @param s 指定的排序的Set集合
 * @throws NullPointerException 如果指定集合 或者 它的任意元素 为null
 */
public ConcurrentSkipListSet(SortedSet<E> s) {
    //调用对应的ConcurrentSkipListMap的构造器
    m = new ConcurrentSkipListMap<E, Object>(s.comparator());
    //调用addAll方法
    addAll(s);
}

2.2 API方法

  API方法都是通过内部的ConcurrentSkipListMap的方法来进行代理调用的,非常简单,put操作的key就是我们传入的元素,value是一个固定的Boolean.TRUE对象,没什么用,这些方法的源码我们在ConcurrentSkipListMap的部分已经都讲解过了。
  读操作具有弱一致性,只能保证数据的最终一致性。迭代器是fail-safe的,不会抛出ConcurrentModificationException异常,但也不支持写操作。

/**
 * 如果指定的元素尚未存在,则将该元素添加到此Set集合
 *
 * @param e 指定元素
 * @return 如果此集尚未包含指定的元素
 * @throws ClassCastException   如果 e 无法与此 set 中的当前元素进行比较
 * @throws NullPointerException 如果指定的元素为 null
 */
public boolean add(E e) {
    //调用m的putIfAbsent方法,putIfAbsent方法表示:如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null
    //由于ConcurrentSkipListMap要求key和value不能为null,所以这里调用m的put方法的时候,传入的key就是指定元素,传入的value固定为同一个一个Boolean.TRUE对象
    //该value实际上对于set集合来说没有无意义,仅仅是满足ConcurrentSkipListMap的要求。
    return m.putIfAbsent(e, Boolean.TRUE) == null;
}

/**
 * 如果此 set 中存在指定的元素,则将其移除。
 *
 * @param o 指定元素
 * @return 如果此 set 中包含指定的元素,则返回 true
 * @throws ClassCastException   如果 o 无法与此 set 中的当前元素进行比较
 * @throws NullPointerException 如果指定的元素为 null
 */
public boolean remove(Object o) {
    //调用m的remove方法
    return m.remove(o, Boolean.TRUE);
}

/**
 * 从此 set 中移除所有元素。
 */
public void clear() {
    //调用m的clear方法
    m.clear();
}

/**
 * @return 返回此 set 中的元素数目。如果此 set 包含的元素数大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
 */
public int size() {
    //调用m的size方法
    return m.size();
}

/**
 * @return 如果此 set 不包含任何元素,则返回 true。
 */
public boolean isEmpty() {
    //调用m的isEmpty方法
    return m.isEmpty();
}

/**
 * 如果此 set 包含指定的元素,则返回 true。
 *
 * @param o 指定元素
 * @return 如果此 set 包含指定的元素,则返回 true
 * @throws ClassCastException   如果 o 无法与此 set 中的当前元素进行比较
 * @throws NullPointerException 如果指定的元素为 null
 */
public boolean contains(Object o) {
    //调用m的containsKey方法
    return m.containsKey(o);
}

//………………

相关文章:
  JUC—三万字的ConcurrentSkipListMap源码深度解析

如果有什么不懂或者需要交流,可以留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

猜你喜欢

转载自blog.csdn.net/weixin_43767015/article/details/107501635