HashSet se basa en HashMap.
Si nos fijamos en la HashSet<E>implementación, todo se gestiona bajo HashMap<E,Object>.
<E>se usa como clave de HashMap.
Y sabemos que HashMapno es seguro para subprocesos. Por eso tenemos ConcurrentHashMapen Java.
En base a esto, estoy confundido porque no tenemos un ConcurrentHashSet que debería basarse en el ConcurrentHashMap?
¿Hay algo más que me estoy perdiendo? Necesito usar Seten un entorno multiproceso.
Además, si quiero crear el mío, ConcurrentHashSet¿puedo lograrlo simplemente reemplazando el HashMapto ConcurrentHashMapy dejando el resto como está?
java
collections
concurrency
hashmap
hashset
Talha Ahmed Khan
fuente
fuente

ConcurrentSkipListSetse basaConcurrentSkipListMap, que implementaConcurrentNavigableMapyConcurrentMap.Respuestas:
No hay un tipo incorporado
ConcurrentHashSetporque siempre puedes derivar un conjunto de un mapa. Como hay muchos tipos de mapas, utiliza un método para producir un conjunto a partir de un mapa determinado (o clase de mapa).Antes de Java 8, produce un conjunto de hash simultáneo respaldado por un mapa de hash simultáneo, mediante el uso de
Collections.newSetFromMap(map)En Java 8 (señalado por @Matt), puede obtener una vista de conjunto de hash simultáneo a través de
ConcurrentHashMap.newKeySet(). Esto es un poco más simple que el anteriornewSetFromMapque requería que pasaras un objeto de mapa vacío. Pero es específico deConcurrentHashMap.De todos modos, los diseñadores de Java podrían haber creado una nueva interfaz de conjunto cada vez que se creó una nueva interfaz de mapa, pero ese patrón sería imposible de aplicar cuando terceros creen sus propios mapas. Es mejor tener los métodos estáticos que derivan nuevos conjuntos; ese enfoque siempre funciona, incluso cuando crea sus propias implementaciones de mapas.
fuente
ConcurrentHashMap, pierde los beneficios que obtendríaConcurrentHashMap?newSetFromMapLa implementación se encuentra a partir de la línea 3841 en docjar.com/html/api/java/util/Collections.java.html . Es solo una envoltura ...Collections.newSetFromMapcrea aSetFromMap. por ejemplo, elSetFromMap.removeAllmétodo delega aKeySetView.removeAll, que hereda deConcurrentHashMap$CollectionView.removeAll. Este método es altamente ineficiente en la eliminación de elementos a granel. imagineremoveAll(Collections.emptySet())atraviesa todos los elementosMapsin hacer nada. Tener unaConcurrentHashSetimplementación correcta será mejor en la mayoría de los casos.fuente
Con Guava 15 también puedes usar simplemente:
fuente
Como Ray Toal mencionó, es tan fácil como:
fuente
ConcurrentHashMap.Parece que Java proporciona una implementación de conjunto concurrente con su ConcurrentSkipListSet . Un conjunto SkipList es solo un tipo especial de implementación de conjunto. Todavía implementa las interfaces Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet. Esto podría funcionar para usted si solo necesita la interfaz Set.
fuente
ConcurrentSkipListSetlos elementos deben serComparableConcurrentSkipListSetmenos que quiera unSortedSet. Una operación habitual como agregar o quitar debería ser O (1) para aHashSet, pero O (log (n)) para aSortedSet.Como se ha señalado por esta la mejor manera de obtener un HashSet concurrencia-poder es por medio de
Collections.synchronizedSet()Esto funcionó para mí y no he visto a nadie realmente señalando.
EDITAR Esto es menos eficiente que la solución aprobada actualmente, como señala Eugene, ya que simplemente envuelve su conjunto en un decorador sincronizado, mientras que en
ConcurrentHashMaprealidad implementa una concurrencia de bajo nivel y puede respaldar su Conjunto igual de bien. Así que gracias al Sr. Stepanenkov por dejar eso claro.http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-
fuente
synchronizedSetmétodo que se acaba crea el decorador bajoCollectiona los métodos de envoltura que podrían ser thread-safe por sincronización de toda la colección. PeroConcurrentHashMapse implementa utilizando algoritmos sin bloqueo y sincronizaciones de "bajo nivel" sin ningún bloqueo de toda la colección. Entonces, los wrapers deCollections.synchronized... son peores en entornos de subprocesos múltiples por razones de rendimiento.Puedes usar guayabas
Sets.newSetFromMap(map)para conseguir uno. Java 6 también tiene ese método enjava.util.Collectionsfuente
fuente
¿Por qué no usar: CopyOnWriteArraySet de java.util.concurrent?
fuente