您的位置:首页 > 其它

并发容器之ConcurrentSkipListSet

2016-08-05 17:25 525 查看

概要

本章对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的数据结构,如下图所示:

View Code
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异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: