Dlaczego nie ma ConcurrentHashSet przeciwko ConcurrentHashMap

HashSet jest oparty na Hashmapie.

Jeśli spojrzymy na HashSet<E> implementację, wszystko jest zarządzane pod HashMap<E,Object>.

<E> jest używany jako klucz HashMap.

I wiemy, że HashMap nie jest bezpieczny. Dlatego mamy ConcurrentHashMap w Javie.

Bazując na tym, jestem zdezorientowany, że dlaczego nie mamy zestawu współbieżności, który powinien być oparty na ConcurrentHashMap?

Czy coś jeszcze mi umyka? Muszę użyć Set w wielowątkowym środowisko.

Ponadto, jeśli chcę stworzyć swój własny ConcurrentHashSet Czy Mogę to osiągnąć poprzez zastąpienie HashMap na ConcurrentHashMap i pozostawienie reszty tak, jak jest?

Author: Kevin Panko, 2011-08-09

9 answers

Nie ma wbudowanego typu dla ConcurrentHashSet, ponieważ zawsze możesz wyprowadzić zbiór z mapy. Ponieważ istnieje wiele typów map, można użyć metody do wytworzenia zestawu z danej mapy(lub klasy map).

Przed wersją Java 8 tworzysz współbieżny zestaw hashów wspierany przez współbieżną mapę hashów, używając Collections.newSetFromMap(map)

W Javie 8 (wskazanym przez @ Matt), można uzyskać współbieżny zestaw hashów widok Poprzez ConcurrentHashMap.newKeySet(). Jest to nieco prostsze niż stare newSetFromMap, które wymagały aby przejść w pustym obiekcie mapy. Ale to jest specyficzne dla ConcurrentHashMap.

W każdym razie projektanci Javy mogli stworzyć nowy interfejs zestawu za każdym razem, gdy tworzony był nowy interfejs mapy, ale ten wzór nie byłby możliwy do wyegzekwowania, gdy osoby trzecie tworzą własne mapy. Lepiej mieć statyczne metody, które generują nowe zestawy; takie podejście zawsze działa, nawet jeśli tworzysz własne implementacje map.

 450
Author: Ray Toal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 21:11:55
Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
 80
Author: Serge Mask,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-23 09:29:33

Z guawa 15 Możesz również po prostu użyć:

Set s = Sets.newConcurrentHashSet();
 59
Author: kichik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-06 22:28:26

Jak Ray Toal wspomniał, że jest to tak proste jak:

Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet();
 17
Author: BullyWiiPlaza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:27

Wygląda na to, że Java dostarcza implementację zestawu współbieżnego z jego ConcurrentSkipListSet . Zbiór SkipList jest po prostu specjalnym rodzajem implementacji zestawu. Nadal implementuje Interfejsy Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet. Może to zadziałać, jeśli potrzebujesz tylko interfejsu Set.

 16
Author: Mike Pone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-02 16:17:32

Możesz użyć guava ' S Sets.newSetFromMap(map) żeby je zdobyć. Java 6 ma również tę metodę w java.util.Collections

 12
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-09 07:17:05

Jak wskazano przez Ten Najlepszym sposobem uzyskania HashSet w stanie współbieżności jest Collections.synchronizedSet()

Set s = Collections.synchronizedSet(new HashSet(...));
To zadziałało i nie widziałem, żeby ktoś na to wskazywał.

EDIT jest to mniej wydajne niż obecnie zatwierdzone rozwiązanie, jak podkreśla Eugene, ponieważ po prostu zawija twój zestaw w zsynchronizowany dekorator, podczas gdy ConcurrentHashMap faktycznie implementuje współbieżność niskiego poziomu i może równie dobrze wspierać Twój zestaw. Podziękowania dla Pana Stepanenkova za zrobienie jasne.

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

 11
Author: Nirro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-31 05:10:46
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;
   }
}
 5
Author: MD. Mohiuddin Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 07:14:55

Dlaczego nie użyć: CopyOnWriteArraySet z Javy.util./ align = "left" /

 2
Author: Shendor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-07 14:56:32