概要

本章对Java.util.concurrent包中的ConcurrentSkipListSet类进行详细的介绍。内容包括:
ConcurrentSkipListSet介绍ConcurrentSkipListSet原理和数据结构
ConcurrentSkipListSet函数列表
ConcurrentSkipListSet源码(JDK1.7.0_40版本)
ConcurrentSkipListSet示例

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3498634.html

ConcurrentSkipListSet介绍

ConcurrentSkipListSet是线程安全的有序的集合,适用于高并发的场景。
ConcurrentSkipListSet和TreeSet,它们虽然都是有序的集合。但是,第一,它们的线程安全机制不同,TreeSet是非线程安全的,而ConcurrentSkipListSet是线程安全的。第二,ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的,而TreeSet是通过TreeMap实现的。

ConcurrentSkipListSet原理和数据结构

ConcurrentSkipListSet的数据结构,如下图所示:

说明
(01) ConcurrentSkipListSet继承于AbstractSet。因此,它本质上是一个集合。
(02) ConcurrentSkipListSet实现了NavigableSet接口。因此,ConcurrentSkipListSet是一个有序的集合。
(03) ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的。它包含一个ConcurrentNavigableMap对象m,而m对象实际上是ConcurrentNavigableMap的实现类ConcurrentSkipListMap的实例。ConcurrentSkipListMap中的元素是key-value键值对;而ConcurrentSkipListSet是集合,它只用到了ConcurrentSkipListMap中的key!

ConcurrentSkipListSet函数列表

// 构造一个新的空 set,该 set 按照元素的自然顺序对其进行排序。
ConcurrentSkipListSet()
// 构造一个包含指定 collection 中元素的新 set,这个新 set 按照元素的自然顺序对其进行排序。
ConcurrentSkipListSet(Collection<? extends E> c)
// 构造一个新的空 set,该 set 按照指定的比较器对其元素进行排序。
ConcurrentSkipListSet(Comparator<? super E> comparator)
// 构造一个新 set,该 set 所包含的元素与指定的有序 set 包含的元素相同,使用的顺序也相同。
ConcurrentSkipListSet(SortedSet<E> s) // 如果此 set 中不包含指定元素,则添加指定元素。
boolean add(E e)
// 返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
E ceiling(E e)
// 从此 set 中移除所有元素。
void clear()
// 返回此 ConcurrentSkipListSet 实例的浅表副本。
ConcurrentSkipListSet<E> clone()
// 返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
Comparator<? super E> comparator()
// 如果此 set 包含指定的元素,则返回 true。
boolean contains(Object o)
// 返回在此 set 的元素上以降序进行迭代的迭代器。
Iterator<E> descendingIterator()
// 返回此 set 中所包含元素的逆序视图。
NavigableSet<E> descendingSet()
// 比较指定对象与此 set 的相等性。
boolean equals(Object o)
// 返回此 set 中当前第一个(最低)元素。
E first()
// 返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
E floor(E e)
// 返回此 set 的部分视图,其元素严格小于 toElement。
NavigableSet<E> headSet(E toElement)
// 返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。
NavigableSet<E> headSet(E toElement, boolean inclusive)
// 返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
E higher(E e)
// 如果此 set 不包含任何元素,则返回 true。
boolean isEmpty()
// 返回在此 set 的元素上以升序进行迭代的迭代器。
Iterator<E> iterator()
// 返回此 set 中当前最后一个(最高)元素。
E last()
// 返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
E lower(E e)
// 获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。
E pollFirst()
// 获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。
E pollLast()
// 如果此 set 中存在指定的元素,则将其移除。
boolean remove(Object o)
// 从此 set 中移除包含在指定 collection 中的所有元素。
boolean removeAll(Collection<?> c)
// 返回此 set 中的元素数目。
int size()
// 返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。
NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
// 返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
NavigableSet<E> subSet(E fromElement, E toElement)
// 返回此 set 的部分视图,其元素大于等于 fromElement。
NavigableSet<E> tailSet(E fromElement)
// 返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。
NavigableSet<E> tailSet(E fromElement, boolean inclusive)

ConcurrentSkipListSet源码(JDK1.7.0_40版本)

ConcurrentSkipListSet.java的完整源码如下:

 

ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的,它的接口基本上都是通过调用ConcurrentSkipListMap接口来实现的。这里就不再对它的源码进行分析了。

ConcurrentSkipListSet示例

 1 import java.util.*;
2 import java.util.concurrent.*;
3
4 /*
5 * ConcurrentSkipListSet是“线程安全”的集合,而TreeSet是非线程安全的。
6 *
7 * 下面是“多个线程同时操作并且遍历集合set”的示例
8 * (01) 当set是ConcurrentSkipListSet对象时,程序能正常运行。
9 * (02) 当set是TreeSet对象时,程序会产生ConcurrentModificationException异常。
10 *
11 * @author skywang
12 */
13 public class ConcurrentSkipListSetDemo1 {
14
15 // TODO: set是TreeSet对象时,程序会出错。
16 //private static Set<String> set = new TreeSet<String>();
17 private static Set<String> set = new ConcurrentSkipListSet<String>();
18 public static void main(String[] args) {
19
20 // 同时启动两个线程对set进行操作!
21 new MyThread("a").start();
22 new MyThread("b").start();
23 }
24
25 private static void printAll() {
26 String value = null;
27 Iterator iter = set.iterator();
28 while(iter.hasNext()) {
29 value = (String)iter.next();
30 System.out.print(value+", ");
31 }
32 System.out.println();
33 }
34
35 private static class MyThread extends Thread {
36 MyThread(String name) {
37 super(name);
38 }
39 @Override
40 public void run() {
41 int i = 0;
42 while (i++ < 10) {
43 // “线程名” + "序号"
44 String val = Thread.currentThread().getName() + (i%6);
45 set.add(val);
46 // 通过“Iterator”遍历set。
47 printAll();
48 }
49 }
50 }
51 }

(某一次)运行结果

a1, b1,
a1, a1, a2, b1,
b1, a1, a2, a3, b1, a1, a2, a3, a1, a4, b1, b2,
a2, a1, a2, a3, a4, a5, b1, b2,
a3, a0, a4, a5, a1, b1, a2, b2,
a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3,
a5, a0, b1, a1, b2, a2, b3,
a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3, a5, b4,
b1, a0, b2, a1, b3, a2, b4,
a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3, a5, b4, b1, b5,
b2, a0, a1, a2, a3, a4, a5, b3, b1, b4, b2, b5,
b3, a0, b4, a1, b5,
a2, a0, a3, a1, a4, a2, a5, a3, b0, a4, b1, a5, b2, b0, b3, b1, b4, b2, b5, b3,
b4, a0, b5,
a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5,
a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5,
a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5,
a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5,

结果说明
示例程序中,启动两个线程(线程a和线程b)分别对ConcurrentSkipListSet进行操作。以线程a而言,它会先获取“线程名”+“序号”,然后将该字符串添加到ConcurrentSkipListSet集合中;接着,遍历并输出集合中的全部元素。 线程b的操作和线程a一样,只不过线程b的名字和线程a的名字不同。
当set是ConcurrentSkipListSet对象时,程序能正常运行。如果将set改为TreeSet时,程序会产生ConcurrentModificationException异常。

并发容器之ConcurrentSkipListSet的更多相关文章

  1. Java并发编程:并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  2. Java并发编程:并发容器之ConcurrentHashMap

    转载: Java并发编程:并发容器之ConcurrentHashMap JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的 ...

  3. 【转】Java并发编程:并发容器之ConcurrentHashMap

    JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了 ...

  4. Java并发编程:并发容器之ConcurrentHashMap(转)

    本文转自:http://www.cnblogs.com/dolphin0520/p/3932905.html Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载 ...

  5. 10、Java并发编程:并发容器之ConcurrentHashMap

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  6. 并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 1.7与1.8有很大的区别:h ...

  7. Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

  8. Java并发编程:并发容器之CopyOnWriteArrayList

    转载: Java并发编程:并发容器之CopyOnWriteArrayList Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个 ...

  9. 【转】Java并发编程:并发容器之CopyOnWriteArrayList

    Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...

随机推荐

  1. windows的页自映射机制

    windows下由于启用了页机制,所有软件层面的地址操作都是VA,通过descriptor(base address(32bit))+offset得到的线性地址并不直接对应物理地址,而是经过页转换机构 ...

  2. glibc下的内存管理

    在解码过程中我们也遇到了类似的问题,第一次解码的音频比较大60s,耗了3G的内存,reset之后内存并没有退还给操作系统,第二次即使解一个10s的音频 几周前我曾提到,我被项目组分配去做了一些探究li ...

  3. 自然语言处理1——语言处理与Python(内含纠错)

    学习Python自然语言处理,记录一下学习笔记. 运用Python进行自然语言处理需要用到nltk库,关于nltk库的安装,我使用的pip方式. pip nltk 或者下载whl文件进行安装.(推荐p ...

  4. sed 神器

    1.  删除一行 sed -i "1d" sedtest.txt 删除 sedtest.txt   第一行 2.  插入一行 sed '1i\0 ' sedtest.txt  &g ...

  5. 怎么让OCR文字识别软件转换别的语言文档

    ABBYY PDF Transformer+让您可创建或转换希伯来语.意第绪语.日语.中文.泰语.韩语和阿拉伯语的文档.那么如何顺利使用这些复杂语言文字呢?小编教你两步骤轻松快速处理包含以下复杂语言文 ...

  6. JavaScript 的字符串转换

    数字.布尔值等其他数据类型都可以转换成字符串:一般来说,脚本引擎将根据上下文自动完成这样的转换.例如,当把数字或布尔型变量传给希望接收字符串变量的函数时,就会先隐式地将该数值转换成字符串,再进行处理: ...

  7. c编码-2

    1.重设socket缓冲区 系统提供的socket缓冲区大小为8K,你可以将之设置为64K,尤其在传输实时视频时. [root@8A_3 src]# gcc socka.c[root@8A_3 src ...

  8. OpenJudge计算概论-中位数

    /*============================================================== 中位数 总时间限制: 2000ms 内存限制: 65536kB 描述 ...

  9. Jenkins初探

    最近搞搞接口测试,Postman脚本搞好了,但是每次都要手动运行,是不是太low了?Yes,it is. 最近好多人都在用Jenkins搞自动化部署集成之类的,我也凑热闹搞一下. 前提: 1. 已经安 ...

  10. maven Spring 4.2+SpringMVC+dubbo解决TypeProxyInvocationHandler.invoke(SerializableTypeWrapper.java:239)

    java.lang.NullPointerException org.springframework.core.SerializableTypeWrapper$TypeProxyInvocationH ...