16-包装线程不安全的集合

Collections 包装集合成为线程安全

集合中 ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap 等都是线程不安全的。当多个并发线程向这些集合中存取元素时,就可能破坏集合中数据的完整性。

使用 Collections 工具类可以把这些集合包装成线程安全的集合:

  • Collection synchronizedCollection(Collection c):返回指定 collection 对应的线程安全的 collection。
  • static List synchronizedList(List list):返回指定 List 对象对应的线程安全的 List 对象。
  • static <K,V> Map<K,V> synchronizedMap(Map<K,V> m):返回指定 Map 对象对应的线程安全的 Map 对象。
  • static Set synchronizedSet(Set s):返回指定 Set 对象对应的线程安全的 Set 对象。
  • static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m):返回指定 SortedMap 对象对应的线程安全的 SortedMap 对象。
  • static SortedSet synchronizedSortedSet(SortedSet s):返回指定 SortedSet 对象对应的线程安全的 SortedSet 对象。

例如要在多线程环境中使用线程安全的 HashMap 对象:

1
HashMap m=Collectoins.synchronizedMap(new HashMap());

要注意,应该在创建之后立即把集合包装成线程安全的集合。

java.util.concurrent 包提供的线程安全的集合类

java.util.concurrent 包提供了大量支持高效并发访问的集合接口和实现类,可分为两种:

  • 以 Concurrent 开头的集合类,如 ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、ConcurrentLinkedQueue 和 ConcurrentLinkedDeque。
  • 以 CopyOnWrite 开头的集合类,如 CopyWriteArrayList、CopyOnWriteArraySet。

以 Concurrent 开头的集合类代表了支持并发访问的集合,它们可以支持多个线程并发写入访问,这些写入线程的所有操作都是线程安全的,但读取操作不必锁定。在并发写入时有较好的性能。

以 CopyWriteArraySet 的底层封装了