In Java
, there is thread-safe version HashMap named ConcurrentHashMap and thread-safe version TreeMap named ConcurrentSkipListMap, but there is no ConcurrentHashSet
for HashSet.
Instead, there are usually 4 ways to use thread-safe Set
:
Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
Set<String> s = Collections.synchronizedSet(new HashSet<String>());
ConcurrentSkipListSet<E>
CopyOnWriteArraySet<E>
1 use keySet()
of ConcurrentHashMap
to achieve both Set
and thread-safe.
2 use synchronized
way, it seems this way is not recommended.
3 is based on ConcurrentSkipListMap
and is widely used.
4 is based on CopyOnWriteArrayList, thus it shares the same basic properties of CopyOnWriteArrayList
. Following is select from CopyOnWriteArraySet
doc: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html
Since 1 and 3 are commonly used, why does CopyOnWriteArraySet
exist? When is CopyOnWriteArraySet
useful?
Added: CopyOnWriteArraySet
is based on CopyOnWriteArrayList
, and the contains
operation in List
data structure is O(n), while Set
data structure is for high performance contains
operation, could anybody explain this?
It is useful when you have a small set of element for a thread safe collection.
One example is a Set of listeners. You need to ensure uniqueness and iterate over them efficiently.
BTW CopyOnWriteArraySet has the lowest overhead on a per reference basis. It can be as little as 1/6 the size of the other collections. This is particularly useful if you have a lot of them.
while Set data structure is for high performance contains operation, could anybody explain this?
COWAS is more efficient in terms of memory and it's contains
is faster for small collections than the alternatives. What is "high performance" depends on the use case.