[英]Why there is no ConcurrentHashSet against ConcurrentHashMap
HashSet is based on HashMap. HashSet 基于 HashMap。
If we look at HashSet<E>
implementation, everything is been managed under HashMap<E,Object>
.如果我们看一下
HashSet<E>
的实现,一切都在HashMap<E,Object>
下进行管理。
<E>
is used as a key of HashMap
. <E>
用作HashMap
的密钥。
And we know that HashMap
is not thread safe.而且我们知道
HashMap
不是线程安全的。 That is why we have ConcurrentHashMap
in Java.这就是为什么我们在 Java 中有
ConcurrentHashMap
。
Based on this, I am confused that why we don't have a ConcurrentHashSet which should be based on the ConcurrentHashMap
?基于此,我很困惑为什么我们没有应该基于 ConcurrentHashMap 的
ConcurrentHashMap
?
Is there anything else that I am missing?还有什么我想念的吗? I need to use
Set
in a multi-threaded environment.我需要在多线程环境中使用
Set
。
Also, If I want to create my own ConcurrentHashSet
can I achieve it by just replacing the HashMap
to ConcurrentHashMap
and leaving the rest as is?另外,如果我想创建自己的
ConcurrentHashSet
,我可以通过将HashMap
替换为ConcurrentHashMap
并将 rest 保持原样来实现吗?
There's no built in type for ConcurrentHashSet
because you can always derive a set from a map. ConcurrentHashSet
没有内置类型,因为您总是可以从地图派生一个集合。 Since there are many types of maps, you use a method to produce a set from a given map (or map class). 由于有许多类型的地图,因此您可以使用方法从给定地图(或地图类)生成集合。
Prior to Java 8, you produce a concurrent hash set backed by a concurrent hash map, by using Collections.newSetFromMap(map)
在Java 8之前,通过使用
Collections.newSetFromMap(map)
生成由并发哈希映射支持的并发哈希Collections.newSetFromMap(map)
In Java 8 (pointed out by @Matt), you can get a concurrent hash set view via ConcurrentHashMap.newKeySet()
. 在Java 8(由@Matt指出)中,您可以通过
ConcurrentHashMap.newKeySet()
获得并发哈希集视图 。 This is a bit simpler than the old newSetFromMap
which required you to pass in an empty map object. 这比旧的
newSetFromMap
要简单得多,后者要求你传入一个空的地图对象。 But it is specific to ConcurrentHashMap
. 但它特定于
ConcurrentHashMap
。
Anyway, the Java designers could have created a new set interface every time a new map interface was created, but that pattern would be impossible to enforce when third parties create their own maps. 无论如何,每次创建新的地图界面时,Java设计者都可以创建一个新的集合界面,但是当第三方创建自己的地图时,该模式将无法实施。 It is better to have the static methods that derive new sets;
最好使用派生新集的静态方法; that approach always works, even when you create your own map implementations.
即使您创建自己的地图实现,该方法也始终有效。
Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
使用Guava 15,您还可以使用:
Set s = Sets.newConcurrentHashSet();
就像Ray Toal所提到的那样简单:
Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet();
It looks like Java provides a concurrent Set implementation with its ConcurrentSkipListSet . 看起来Java提供了ConcurrentSkipListSet的并发Set实现。 A SkipList Set is just a special kind of set implementation.
SkipList Set只是一种特殊的集合实现。 It still implements the Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet interfaces.
它仍然实现Serializable,Cloneable,Iterable,Collection,NavigableSet,Set,SortedSet接口。 This might work for you if you only need the Set interface.
如果您只需要Set接口,这可能对您有用。
As pointed by this the best way to obtain a concurrency-able HashSet is by means of Collections.synchronizedSet()
正如指出由此 ,获得并发能够HashSet的最好的办法是借助于
Collections.synchronizedSet()
Set s = Collections.synchronizedSet(new HashSet(...));
This worked for me and I haven't seen anybody really pointing to it. 这对我有用,我没有看到任何人真正指向它。
EDIT This is less efficient than the currently aproved solution, as Eugene points out, since it just wraps your set into a synchronized decorator, while a ConcurrentHashMap
actually implements low-level concurrency and it can back your Set just as fine. 编辑这比当前被批准的解决方案效率低,正如Eugene所指出的那样,因为它只是将你的集合包装成一个同步的装饰器,而
ConcurrentHashMap
实际上实现了低级别的并发性,它可以支持你的Set一样好。 So thanks to Mr. Stepanenkov for making that clear. 所以感谢Stepanenkov先生说清楚了。
http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set- http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-
You can use guava's Sets.newSetFromMap(map)
to get one. 您可以使用guava的
Sets.newSetFromMap(map)
来获取一个。 Java 6 also has that method in java.util.Collections
Java 6在
java.util.Collections
也有该方法
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>{
private final ConcurrentMap<E, Object> theMap;
private static final Object dummy = new Object();
public ConcurrentHashSet(){
theMap = new ConcurrentHashMap<E, Object>();
}
@Override
public int size() {
return theMap.size();
}
@Override
public Iterator<E> iterator(){
return theMap.keySet().iterator();
}
@Override
public boolean isEmpty(){
return theMap.isEmpty();
}
@Override
public boolean add(final E o){
return theMap.put(o, ConcurrentHashSet.dummy) == null;
}
@Override
public boolean contains(final Object o){
return theMap.containsKey(o);
}
@Override
public void clear(){
theMap.clear();
}
@Override
public boolean remove(final Object o){
return theMap.remove(o) == ConcurrentHashSet.dummy;
}
public boolean addIfAbsent(final E o){
Object obj = theMap.putIfAbsent(o, ConcurrentHashSet.dummy);
return obj == null;
}
}
为什么不使用:java.util.concurrent中的CopyOnWriteArraySet?
We have ConcurrentHashSet in io.vertx which can be used against java.util ConcurrentHashMap.我们在 io.vertx 中有 ConcurrentHashSet,它可以用于 java.util ConcurrentHashMap。 https://www.javadoc.io/static/io.vertx/vertx-core/3.0.0/io/vertx/core/impl/ConcurrentHashSet.html
https://www.javadoc.io/static/io.vertx/vertx-core/3.0.0/io/vertx/core/impl/ConcurrentHashSet.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.