ConcurrentSkipListSet 的使用

相关阅读:并发容器之ConcurrentSkipListSet

java.util.concurrent 包下 并发安全有序 Set(NavigableSet),基于 ConcurrentSkipListMap 实现。可以进行有序遍历、范围查找,并且并发安全。底层原理即 跳表 数据结构。

新建该集合对象时,可以在构造方法中传一个 Comparator<E> 对象,用于元素比较。

值得注意的是,如果 Comparator 的 compare 方法中读取的是 E 对象的可变成员变量,可能会造成在集合中查找该元素失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private static class Bean {
private Date updateTime;
public Bean(Date date) {
updateTime = date;
}
}

@Test
public void concurrentSkipListSetTest() {
ConcurrentSkipListSet<Bean> skipListSet = new ConcurrentSkipListSet<>(Comparator.comparingLong(b -> b.updateTime.getTime()));
//填充一百个元素,使跳表具有一定深度
for (int i = 0; i < 100; i++) {
skipListSet.add(new Bean(new Date(i * 100)));
}
//2900
System.out.println(skipListSet.lower(new Bean(new Date(3000))).updateTime.getTime());
Bean bean = skipListSet.first();
//0
System.out.println(bean.updateTime.getTime());
//true
System.out.println(skipListSet.contains(bean));
bean.updateTime = new Date(99999999);
//由于 skipListSet 中的比较器取的 bean 的 updateTime 进行比较
//导致在 updateTime 改变时,元素无法路由到跳表集合中的原位置
//false
System.out.println(skipListSet.contains(bean));
bean.updateTime = new Date(10);
//将 updateTime 修改为 10,可以路由到第一个元素
//true
System.out.println(skipListSet.contains(bean));
}