HashMap vs. ConcurrentHashMap vs. SynchronizedMap – Como um HashMap pode ser sincronizado em Java

Publicados: 2015-01-29

Crunchify ConcurrentHashMap vs. Exemplo de mapa sincronizado HashMap é uma estrutura de dados muito poderosa em Java. Nós o usamos todos os dias e quase em todas as aplicações. Existem alguns exemplos que escrevi antes em Como implementar o cache Threadsafe, Como converter Hashmap em Arraylist?

Usamos Hashmap em ambos os exemplos acima, mas esses são casos de uso bastante simples de Hashmap. HashMap is a non-synchronized .

Você tem alguma das perguntas abaixo?

  • Qual é a diferença entre ConcurrentHashMap e Collections.synchronizedMap(Map)?
  • Qual é a diferença entre ConcurrentHashMap e Collections.synchronizedMap(Map) em termos de desempenho?
  • ConcurrentHashMap vs Collections.synchronizedMap()
  • Perguntas populares da entrevista sobre HashMap e ConcurrentHashMap

Neste tutorial, abordaremos todas as consultas acima e why and how podemos sincronizar o Hashmap?

Por quê?

O objeto Map é um container associativo que armazena elementos, formado por uma combinação de uma key de identificação exclusiva e um value mapeado. Se você tem um aplicativo altamente simultâneo no qual pode querer modificar ou ler o valor da chave em diferentes threads, é ideal usar o Hashmap Concorrente. O melhor exemplo é o Producer Consumer, que lida com leitura/gravação simultânea.

Então, o que significa o mapa thread-safe? Se multiple threads acessarem um mapa de hash simultaneamente e pelo menos um dos encadeamentos modificar o mapa estruturalmente, ele must be synchronized externally para evitar uma visualização inconsistente do conteúdo.

Quão?

Existem duas maneiras de sincronizar o HashMap

  1. Método das Coleções Java SynchrodMap()
  2. Usar ConcurrentHashMap

ConcurrentHashMap

  • Você deve usar ConcurrentHashMap quando precisar de simultaneidade muito alta em seu projeto.
  • É thread-safe sem sincronizar whole map .
  • As leituras podem acontecer muito rapidamente enquanto a gravação é feita com um bloqueio.
  • Não há bloqueio no nível do objeto.
  • O bloqueio está em uma granularidade muito mais fina em um nível de bucket de hashmap.
  • ConcurrentHashMap não lança um ConcurrentModificationException se um thread tentar modificá-lo enquanto outro estiver iterando sobre ele.
  • ConcurrentHashMap usa vários bloqueios.

SynchronizedHashMap

  • Sincronização em nível de objeto.
  • Toda operação de leitura/gravação precisa adquirir bloqueio.
  • Bloquear toda a coleção é uma sobrecarga de desempenho.
  • Isso essencialmente dá acesso a apenas um thread para todo o mapa e bloqueia todos os outros threads.
  • Pode causar contenção.
  • SynchronizedHashMap retorna Iterator , que falha rapidamente na modificação simultânea.

Agora vamos dar uma olhada no código

  1. Criar classe CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. Criar objeto para cada HashTable, SynchronizedMap e CrunchifyConcurrentHashMap
  3. Adicione e recupere 500 mil entradas do Mapa
  4. Meça o tempo de início e término e o tempo de exibição em milissegundos
  5. Usaremos ExecutorService para executar 5 threads em paralelo

Aqui está um código Java:

  • shutdown() significa que o serviço executor não recebe mais tarefas.
  • awaitTermination() é invocado após uma solicitação de desligamento.

E, portanto, você precisa primeiro desligar o serviceExecutor e, em seguida, bloquear e aguardar a conclusão dos encadeamentos.

Resultado do Console do Eclipse: