Collections.newSetFromMap(»ConcurrentHashMap«) vs. Collections.synchronizedSet(»HashSet«)

显然,有两种方法可以使用Java的集合实用程序类获取线程安全的HashSet实例。

我问:

  • 它们有何不同?
  • 在什么情况下,哪一种优先于另一种?

答案 1

你可能想到的是

Set<Type> set = Collections.newSetFromMap(new ConcurrentHashMap<Type, Boolean>());

这支持并发更新和读取。它的迭代器不会抛出 ConcurrentModicationException。其中作为

Set<Type> set = Collections.synchronizedSet(new HashSet<Type());

重量更轻,但一次只允许一个线程访问该集。如果要迭代该集,则需要显式锁定该集,并且如果您不以安全的方式更新它(在迭代它时),您仍然可以获得CME。


答案 2

第一个返回一个 Set,该 Set 基本上具有与作为参数传递的映射相同的线程安全和性能保证。如果映射不是线程安全的,则该集也不会是线程安全的。通常使用此方法从并发映射创建并发集,因为 API 中没有 ConcurrentHashSet。

第二个将代理返回到给定的集合,该集合已同步其所有方法。