并发容器之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异常。
相关文章推荐
- Redis 持久化
- HashCode 使用产生Utils类
- div的几种声明控制
- 基于DragonBoard 410c android系统实现红外遥控功能
- 接口和抽象类
- 圆锥与圆柱
- 欢迎使用CSDN-markdown编辑器
- 理解SVG坐标系统和变换: transform属性
- LeetCode | Binary Tree Preorder Traversal
- Java 集合:Map 系列(WeakHashMap概念)
- JAVA中session实现原理
- iBatis动态条件查询
- HDU 3232 Crossing Rivers (数学期望)
- Android Studio使用过程中常见问题及解决方案
- constexpr-C++11
- Java 集合:Map 系列(ConcurrentHashMap概念)
- bower 是什么,怎么使用
- jdk替换
- Android开发之路的起点
- 八大排序算法--直接选择排序