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
- It is best suited for applications in which set sizes generally stay small, read-only operations vastly outnumber mutative operations, and you need to prevent interference among threads during traversal.
- It is thread-safe.
- Mutative operations (add, set, remove, etc.) are expensive since they usually entail copying the entire underlying array.
- Iterators do not support the mutative remove operation.
- Traversal via iterators is fast and cannot encounter interference from other threads.
- Iterators rely on unchanging snapshots of the array at the time the iterators were constructed.
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?