java java线程安全set concurrentskiplistset - 为什么没有针对ConcurrentHashMap的ConcurrentHashSet




5 Answers

ConcurrentHashSet没有内置类型,因为您始终可以从地图派生一个集合。 由于地图类型很多,因此您可以使用一种方法从给定的地图(或地图类)生成一个集合。

在Java 8之前,您通过使用Collections.newSetFromMap(map)生成由并发散列映射支持的并发散列集,

在Java 8中(由@Matt指出),你可以通过ConcurrentHashMap.newKeySet()获得一个并发散列集合视图 。 这比旧的newSetFromMap要求你传入一个空的地图对象要简单一些。 但它特定于ConcurrentHashMap

无论如何,每当创建一个新的地图界面时,Java设计人员都可能创建了一个新的设置界面,但是当第三方创建他们自己的地图时,这种模式将无法执行。 拥有派生新集合的静态方法会更好; 即使您创建自己的地图实现,该方法也可以正常工作。

HashSet基于HashMap。

如果我们看一下HashSet<E>实现,所有东西都在HashMap<E,Object>下进行管理。

<E>被用作HashMap的关键字。

我们知道HashMap不是线程安全的。 这就是为什么我们有Java中的ConcurrentHashMap

基于此,我很困惑, 为什么我们没有一个ConcurrentHashSet应该基于ConcurrentHashMap

还有什么我失踪? 我需要在多线程环境中使用Set

另外,如果我想创建自己的ConcurrentHashSet ,我可以通过将HashMap替换为ConcurrentHashMap并将剩下的部分保持原样来实现它?




使用Guava 15,您也可以简单地使用:

Set s = Sets.newConcurrentHashSet();






正如所指出的那样,获得可并发HashSet的最佳方式是通过Collections.synchronizedSet()

Set s = Collections.synchronizedSet(new HashSet(...));

这对我有用,我还没有看到任何人真的指出它。

正如Eugene指出的那样,这比目前推荐的解决方案效率低,因为它只是将您的集合包装到同步装饰器中,而ConcurrentHashMap实际上实现了低层次并发,并且它可以支持您的集合一样好。 谢谢Stepanenkov先生明确表示。

http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-




为什么不使用:java.util.concurrent的CopyOnWriteArraySet?




Related