【发布时间】:2015-05-28 18:32:29
【问题描述】:
在Java 中,有名为ConcurrentHashMap 的线程安全版本HashMap 和名为ConcurrentSkipListMap 的线程安全版本ConcurrentSkipListMap,但HashSet 没有ConcurrentHashSet。
相反,通常有 4 种方法可以使用线程安全的Set:
Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());Set<String> s = Collections.synchronizedSet(new HashSet<String>());ConcurrentSkipListSet<E>CopyOnWriteArraySet<E>
1 使用keySet() 或ConcurrentHashMap 来实现Set 和线程安全。
2使用synchronized的方式,好像不推荐这种方式。
3 基于ConcurrentSkipListMap,被广泛使用。
4 基于CopyOnWriteArrayList,因此它具有与CopyOnWriteArrayList 相同的基本属性。以下是从CopyOnWriteArraySet doc中选择的:http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html
- 它最适合通常保持集合大小的应用程序 小型只读操作的数量远远超过可变操作,并且 您需要在遍历期间防止线程之间的干扰。
- 它是线程安全的。
- 可变操作(添加、设置、删除等)代价高昂,因为它们通常需要复制整个底层数组。
- 迭代器不支持可变删除操作。
- 通过迭代器的遍历速度很快,不会遇到其他线程的干扰。
- 迭代器依赖于构造迭代器时数组的不变快照。
既然常用1和3,那么CopyOnWriteArraySet为什么会存在呢? CopyOnWriteArraySet 什么时候有用?
补充:CopyOnWriteArraySet是基于CopyOnWriteArrayList,contains在List数据结构中的运算是O(n),而@987654349 @ 数据结构用于高性能 contains 操作,有人可以解释一下吗?
【问题讨论】:
-
JDK中确实没有这个native class;但是,您可以使用
Collections.newSetFromMap(new ConcurrentHashMap<>())。
标签: java multithreading collections concurrency java.util.concurrent