Qual é a diferença entre usar a classe wrapper,, SynchronizedMap
on HashMap
e ConcurrentHashMap
?
Ele está apenas sendo capaz de modificar a HashMap
iteração ( ConcurrentHashMap
)?
Qual é a diferença entre usar a classe wrapper,, SynchronizedMap
on HashMap
e ConcurrentHashMap
?
Ele está apenas sendo capaz de modificar a HashMap
iteração ( ConcurrentHashMap
)?
Respostas:
Sincronizado HashMap
:
Cada método é sincronizado usando um bloqueio no nível do objeto. Portanto, os métodos get e put no synchMap adquirem um bloqueio.
Bloquear a coleção inteira é uma sobrecarga de desempenho. Enquanto um thread mantém o bloqueio, nenhum outro thread pode usar a coleção.
ConcurrentHashMap
foi introduzido no JDK 5.
Não há bloqueio no nível do objeto. O bloqueio tem uma granularidade muito mais fina. Para a ConcurrentHashMap
, os bloqueios podem estar no nível do bloco de hashmap.
O efeito do bloqueio de nível inferior é que você pode ter leitores e gravadores simultâneos, o que não é possível para coleções sincronizadas. Isso leva a muito mais escalabilidade.
ConcurrentHashMap
não lança a ConcurrentModificationException
se um thread tentar modificá-lo enquanto outro está iterando sobre ele.
Este artigo Java 7: HashMap vs ConcurrentHashMap é uma leitura muito boa. Altamente recomendado.
ConcurrentHashMap
o size()
resultado pode estar desatualizado. size()
tem permissão para retornar uma aproximação em vez de uma contagem exata, de acordo com o livro "Java Concurrency in Practice". Portanto, esse método deve ser usado com cuidado.
A resposta curta:
Ambos os mapas são implementações seguras de encadeamento da Map
interface. ConcurrentHashMap
é implementado para maior taxa de transferência nos casos em que alta simultaneidade é esperada.
O artigo de Brian Goetz sobre a idéia por trás ConcurrentHashMap
é uma leitura muito boa. Altamente recomendado.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
é seguro para threads sem sincronizar o mapa inteiro. As leituras podem acontecer muito rapidamente enquanto a gravação é feita com um bloqueio.
Podemos obter segurança de encadeamento usando ConcurrentHashMap e synchronisedHashmap. Mas há muita diferença se você olhar para a arquitetura deles.
Manterá a trava no nível do objeto. Portanto, se você deseja executar qualquer operação como put / get, é necessário adquirir o bloqueio primeiro. Ao mesmo tempo, outros threads não têm permissão para executar nenhuma operação. Portanto, por vez, apenas um segmento pode operar com isso. Portanto, o tempo de espera aumentará aqui. Podemos dizer que o desempenho é relativamente baixo quando você está comparando com o ConcurrentHashMap.
Manterá a trava no nível do segmento. Possui 16 segmentos e mantém o nível de simultaneidade como 16 por padrão. Portanto, por vez, 16 threads podem operar no ConcurrentHashMap. Além disso, a operação de leitura não requer um bloqueio. Portanto, qualquer número de threads pode executar uma operação get nele.
Se o thread1 deseja executar a operação de put no segmento 2 e o thread2 deseja executar a operação de put no segmento 4, isso é permitido aqui. Significa que 16 threads podem executar uma operação de atualização (colocar / excluir) no ConcurrentHashMap de cada vez.
Para que o tempo de espera seja menor aqui. Portanto, o desempenho é relativamente melhor que o hashmap sincronizado.
Ambos são versão sincronizada do HashMap, com diferenças em sua funcionalidade principal e em sua estrutura interna.
ConcurrentHashMap consiste em segmentos internos que podem ser vistos como HashMaps independentes conceitualmente. Todos esses segmentos podem ser bloqueados por threads separados em execuções altas simultâneas. Portanto, vários encadeamentos podem obter / colocar pares de valores-chave no ConcurrentHashMap sem bloquear / esperar um pelo outro. Isso é implementado para maior produtividade.
enquanto que
Collections.synchronizedMap () , obtemos uma versão sincronizada do HashMap e é acessada de maneira bloqueadora. Isso significa que, se vários threads tentarem acessar o synchronizedMap ao mesmo tempo, eles poderão obter / colocar pares de valores-chave, um de cada vez, de maneira sincronizada.
ConcurrentHashMap
usa um mecanismo de bloqueio mais refinado conhecido como lock stripping
permitir maior grau de acesso compartilhado. Devido a isso, fornece melhor simultaneidade e escalabilidade .
Os iteradores retornados também ConcurrentHashMap
são fracamente consistentes, em vez da técnica de falha rápida usada pelo HashMap sincronizado.
Os métodos SynchronizedMap
mantêm a trava no objeto, enquanto que ConcurrentHashMap
existe um conceito de "faixa de trava", na qual as trava são mantidas em baldes do conteúdo. Melhor escalabilidade e desempenho.
ConcurrentHashMap:
1) Ambos os mapas são implementações de thread-safe da interface Map.
2) ConcurrentHashMap é implementado para maior taxa de transferência nos casos em que alta simultaneidade é esperada.
3) Não há bloqueio no nível do objeto.
Mapa de Hash Sincronizado:
1) Cada método é sincronizado usando um bloqueio no nível do objeto.
ConcurrentHashMap permite acesso simultâneo aos dados. O mapa inteiro é dividido em segmentos.
Leia operação ie. get(Object key)
não é sincronizado, mesmo no nível do segmento.
Mas escreva operações ie. remove(Object key), get(Object key)
adquirir bloqueio no nível do segmento. Somente parte do mapa inteiro está bloqueada, outros segmentos ainda podem ler valores de vários segmentos, exceto um bloqueado.
SynchronizedMap, por outro lado, adquire bloqueio no nível do objeto. Todos os threads devem aguardar o thread atual, independentemente da operação (leitura / gravação).
Um teste de desempenho simples para ConcurrentHashMap vs HashMap sincronizado
. O fluxo de teste está chamando put
em um thread e chamando get
três threads Map
simultaneamente. Como disse @trshiv, o ConcurrentHashMap possui maior taxa de transferência e velocidade para operações de leitura sem bloqueio. O resultado é quando o tempo de operação termina 10^7
, ConcurrentHashMap é 2x
mais rápido que o Synchronized HashMap.
SynchronizedMap
e ConcurrentHashMap
são da classe de thread safe e podem ser usados em aplicativos multithread, a principal diferença entre eles é em relação à maneira como eles alcançam a segurança do thread.
SynchronizedMap
adquire bloqueio em toda a instância do Map, enquanto ConcurrentHashMap
divide a instância do Map em vários segmentos e o bloqueio é feito nesses.
Conforme java doc's
Hashtable e Collections.synchronizedMap (novo HashMap ()) são sincronizados. Mas ConcurrentHashMap é "simultâneo".
Uma coleção simultânea é segura para threads, mas não é controlada por um único bloqueio de exclusão.
No caso específico do ConcurrentHashMap, ele permite com segurança qualquer número de leituras simultâneas, bem como um número ajustável de gravações simultâneas. As classes "sincronizadas" podem ser úteis quando você precisa impedir todo o acesso a uma coleção por meio de um único bloqueio, à custa de uma menor escalabilidade.
Em outros casos em que vários threads devem acessar uma coleção comum, versões "simultâneas" são normalmente preferíveis. E coleções não sincronizadas são preferíveis quando as coleções não são compartilhadas ou são acessíveis apenas quando mantêm outros bloqueios.
Hashtable
eSynchronized HashMap
?