HashSet est basé sur HashMap.
Si nous regardons la HashSet<E>
mise en œuvre, tout est géré sous HashMap<E,Object>
.
<E>
est utilisé comme clé de HashMap
.
Et nous savons que ce HashMap
n'est pas sûr pour les threads. C'est pourquoi nous avons ConcurrentHashMap
en Java.
Sur cette base, je ne comprends pas pourquoi nous n'avons pas de ConcurrentHashSet qui devrait être basé sur le ConcurrentHashMap
?
Y a-t-il autre chose qui me manque? Je dois utiliser Set
dans un environnement multi-thread.
De plus, si je veux créer le mien, ConcurrentHashSet
puis-je le réaliser en remplaçant simplement le HashMap
to ConcurrentHashMap
et en laissant le reste tel quel?
java
collections
concurrency
hashmap
hashset
Talha Ahmed Khan
la source
la source
ConcurrentSkipListSet
est construitConcurrentSkipListMap
, qui implémenteConcurrentNavigableMap
etConcurrentMap
.Réponses:
Il n'y a pas de type intégré
ConcurrentHashSet
car vous pouvez toujours dériver un ensemble d'une carte. Comme il existe de nombreux types de cartes, vous utilisez une méthode pour produire un ensemble à partir d'une carte (ou classe de carte) donnée.Avant Java 8, vous produisez un ensemble de hachage simultané soutenu par une carte de hachage simultanée, en utilisant
Collections.newSetFromMap(map)
Dans Java 8 (souligné par @Matt), vous pouvez obtenir une vue d' ensemble de hachage simultanée via
ConcurrentHashMap.newKeySet()
. C'est un peu plus simple que l'anciennewSetFromMap
qui vous obligeait à passer dans un objet de carte vide. Mais c'est spécifique àConcurrentHashMap
.Quoi qu'il en soit, les concepteurs Java auraient pu créer une nouvelle interface d'ensemble à chaque fois qu'une nouvelle interface de carte était créée, mais ce modèle serait impossible à appliquer lorsque des tiers créeraient leurs propres cartes. Il est préférable d'avoir les méthodes statiques qui dérivent de nouveaux ensembles; cette approche fonctionne toujours, même lorsque vous créez vos propres implémentations de carte.
la source
ConcurrentHashMap
, vous perdez les avantages dont vous bénéficieriezConcurrentHashMap
?newSetFromMap
L'implémentation se trouve à partir de la ligne 3841 dans docjar.com/html/api/java/util/Collections.java.html . C'est juste un wrapper ....Collections.newSetFromMap
crée unSetFromMap
. par exemple, laSetFromMap.removeAll
méthode délègue à laKeySetView.removeAll
, qui hérite deConcurrentHashMap$CollectionView.removeAll
. Cette méthode est très inefficace pour retirer des éléments en bloc. imagineremoveAll(Collections.emptySet())
traverse tous les éléments duMap
sans rien faire. Avoir unConcurrentHashSet
qui est correctement implémenté sera mieux dans la plupart des cas.la source
Avec Guava 15, vous pouvez également simplement utiliser:
la source
Comme Ray Toal l'a mentionné, c'est aussi simple que:
la source
ConcurrentHashMap
.Il semble que Java fournisse une implémentation Set simultanée avec son ConcurrentSkipListSet . Un ensemble SkipList n'est qu'un type spécial d'implémentation d'ensemble. Il implémente toujours les interfaces Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet. Cela peut fonctionner pour vous si vous n'avez besoin que de l'interface Set.
la source
ConcurrentSkipListSet
les éléments doivent êtreComparable
ConcurrentSkipListSet
sauf si vous voulez unSortedSet
. Une opération habituelle comme ajouter ou supprimer devrait être O (1) pour aHashSet
, mais O (log (n)) pour aSortedSet
.Comme indiqué par cela, le meilleur moyen d'obtenir un HashSet compatible avec la concurrence est de
Collections.synchronizedSet()
Cela a fonctionné pour moi et je n'ai vu personne le montrer du doigt.
EDITER Ceci est moins efficace que la solution actuellement approuvée, comme le souligne Eugene, car elle enveloppe simplement votre ensemble dans un décorateur synchronisé, tandis qu'un
ConcurrentHashMap
implémente en fait une concurrence de bas niveau et peut sauvegarder votre ensemble tout aussi bien. Merci donc à M. Stepanenkov de l'avoir précisé.http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-
la source
synchronizedSet
méthode crée simplement le décorateur sousCollection
pour envelopper des méthodes qui pourraient être thread-safe en synchronisant toute la collection. MaisConcurrentHashMap
est implémenté à l'aide d' algorithmes non bloquants et de synchronisations "de bas niveau" sans aucun verrouillage de l'ensemble de la collection. Ainsi, les enveloppements deCollections.synchronized
... sont pires dans les environnements multi-threads pour des raisons de performances.Vous pouvez utiliser des goyaves pour
Sets.newSetFromMap(map)
en obtenir un. Java 6 a également cette méthode dansjava.util.Collections
la source
la source
Pourquoi ne pas utiliser: CopyOnWriteArraySet de java.util.concurrent?
la source