HashMap contre. ConcurrentHashMap Vs. SynchronizedMap - Comment un HashMap peut être synchronisé en Java

Publié: 2015-01-29

Crunchify ConcurrentHashMap Vs. Exemple de carte synchronisée HashMap est une structure de données très puissante en Java. Nous l'utilisons tous les jours et presque dans toutes les applications. Il y a pas mal d'exemples que j'ai déjà écrits sur Comment implémenter le cache Threadsafe, Comment convertir Hashmap en Arraylist ?

Nous avons utilisé Hashmap dans les deux exemples ci-dessus, mais ce sont des cas d'utilisation assez simples de Hashmap. HashMap is a non-synchronized .

Avez-vous l'une des questions ci-dessous ?

  • Quelle est la différence entre ConcurrentHashMap et Collections.synchronizedMap(Map) ?
  • Quelle est la différence entre ConcurrentHashMap et Collections.synchronizedMap(Map) en termes de performances ?
  • ConcurrentHashMap vs Collections.synchronizedMap()
  • Questions d'entretien populaires sur HashMap et ConcurrentHashMap

Dans ce didacticiel, nous passerons en revue toutes les requêtes ci-dessus et expliquerons why and how nous pourrions synchroniser Hashmap ?

Pourquoi?

L'objet Map est un conteneur associatif qui stocke des éléments, formé par une combinaison d'une key d'identification unique et d'une value mappée. Si vous avez une application très hautement simultanée dans laquelle vous souhaitez modifier ou lire la valeur de la clé dans différents threads, il est idéal d'utiliser Concurrent Hashmap. Le meilleur exemple est Producer Consumer qui gère la lecture/écriture simultanée.

Alors, que signifie la carte thread-safe ? Si multiple threads accèdent simultanément à une carte de hachage et qu'au moins l'un des threads modifie la carte de manière structurelle, il must be synchronized externally pour éviter une vue incohérente du contenu.

Comment?

Il y a deux façons de synchroniser HashMap

  1. Méthode Java Collections synchronizedMap()
  2. Utiliser ConcurrentHashMap

ConcurrentHashMapConcurrentHashMap

  • Vous devez utiliser ConcurrentHashMap lorsque vous avez besoin d'une simultanéité très élevée dans votre projet.
  • Il est thread-safe sans synchroniser whole map .
  • Les lectures peuvent se produire très rapidement alors que l'écriture est effectuée avec un verrou.
  • Il n'y a pas de verrouillage au niveau de l'objet.
  • Le verrouillage est à une granularité beaucoup plus fine au niveau du compartiment de hashmap.
  • ConcurrentHashMap ne lève pas d'exception ConcurrentModificationException si un thread essaie de le modifier pendant qu'un autre itère dessus.
  • ConcurrentHashMap utilise une multitude de verrous.

SynchronizedHashMapSynchronizedHashMap

  • Synchronisation au niveau de l'objet.
  • Chaque opération de lecture/écriture doit acquérir un verrou.
  • Verrouiller l'ensemble de la collection est une surcharge de performance.
  • Cela donne essentiellement accès à un seul thread à l'ensemble de la carte et bloque tous les autres threads.
  • Cela peut provoquer des conflits.
  • SynchronizedHashMap renvoie Iterator , qui échoue rapidement en cas de modification simultanée.

Voyons maintenant le code

  1. Créer la classe CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. Créer un objet pour chaque HashTable, SynchronizedMap et CrunchifyConcurrentHashMap
  3. Ajouter et récupérer 500 000 entrées à partir de Map
  4. Mesurez l'heure de début et de fin et affichez l'heure en millisecondes
  5. Nous utiliserons ExecutorService pour exécuter 5 threads en parallèle

Voici un code Java :

  • shutdown() signifie que le service exécuteur ne prend plus de tâches entrantes.
  • awaitTermination() est invoqué après une demande d'arrêt.

Et par conséquent, vous devez d'abord arrêter le serviceExecutor, puis bloquer et attendre que les threads se terminent.

Résultat de la console Eclipse :