Dans javadoc pour ConcurrentHashMap est le suivant:
Les opérations de récupération (y compris get) ne bloquent généralement pas, et peuvent donc se chevaucher avec les opérations de mise à jour (y compris put et remove). Les extractions reflètent les résultats des opérations de mise à jour les plus récemment terminées se tenant à leur début. Pour les opérations d'agrégation telles que putAll et clear, les extractions simultanées peuvent refléter l'insertion ou la suppression de seulement certaines entrées. De même, les itérateurs et les énumérations renvoient des éléments reflétant l'état de la table de hachage à un moment donné ou depuis la création de l'itérateur / énumération. Ils ne lèvent pas ConcurrentModificationException. Cependant, les itérateurs sont conçus pour être utilisés par un seul thread à la fois.
Qu'est-ce que ça veut dire? Que se passe-t-il si j'essaie d'itérer la carte avec deux threads en même temps? Que se passe-t-il si je mets ou supprime une valeur de la carte lors de son itération?
ConcurrentModificationException
temps à répéter unConcurrentHashMap
, pourquoi?Vous pouvez utiliser cette classe pour tester deux threads d'accès et un mutant l'instance partagée de
ConcurrentHashMap
:Aucune exception ne sera lancée.
Le partage du même itérateur entre les threads d'accesseurs peut entraîner un blocage:
Dès que vous commencez à partager la même chose
Iterator<Map.Entry<String, String>>
entre les threads accesseurs et mutateurs, les threadsjava.lang.IllegalStateException
commenceront à apparaître.la source
Cela signifie que vous ne devez pas partager un objet itérateur entre plusieurs threads. Créer plusieurs itérateurs et les utiliser simultanément dans des threads séparés est très bien.
la source
Cela pourrait vous donner un bon aperçu
À ce propos:
Cela signifie que si l'utilisation d'itérateurs produits par ConcurrentHashMap dans deux threads est sûre, cela peut provoquer un résultat inattendu dans l'application.
la source
Cela signifie que vous ne devez pas essayer d'utiliser le même itérateur dans deux threads. Si vous avez deux threads qui doivent parcourir les clés, les valeurs ou les entrées, ils doivent chacun créer et utiliser leurs propres itérateurs.
Ce qui se passerait si vous enfreigniez cette règle n’est pas tout à fait clair. Vous pourriez juste avoir un comportement déroutant, de la même manière que vous le faites si (par exemple) deux threads essaient de lire à partir d'une entrée standard sans synchronisation. Vous pouvez également obtenir un comportement non thread-safe.
Mais si les deux threads utilisaient des itérateurs différents, ça devrait aller.
C'est un problème distinct, mais la section javadoc que vous avez citée y répond adéquatement. Fondamentalement, les itérateurs sont thread-safe, mais il n'est pas défini si vous verrez les effets des insertions, mises à jour ou suppressions simultanées reflétées dans la séquence d'objets renvoyés par l'itérateur. En pratique, cela dépend probablement de l'endroit où les mises à jour se produisent sur la carte.
la source