Java
有线程安全版本HashMap,命名为ConcurrentHashMap,线程安全版本TreeMap命名为ConcurrentSkipListMap,但HashSet没有ConcurrentHashSet
。什么时候CopyOnWriteArraySet对实现线程安全的HashSet有用?
相反,通常有4种方式使用线程安全Set
:
Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
Set<String> s = Collections.synchronizedSet(new HashSet<String>());
ConcurrentSkipListSet<E>
CopyOnWriteArraySet<E>
1使用ConcurrentHashMap
keySet()
实现均为Set
和线程安全。
2使用的方式,似乎不推荐这种方式。
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
,并在List
数据结构contains
操作是O(n),而Set
数据结构是高性能contains
操作,可能有人解释一下吗?
在JDK中确实没有这样的本地类;你可以使用'Collections.newSetFromMap(new ConcurrentHashMap <>())'。 – fge 2015-03-25 07:25:24
另一个有用的材料:http://stackoverflow.com/questions/6720396/different-types-of-thread-safe-sets-in-java – coderz 2015-03-27 16:53:02