Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda ConcurrentMap e Suas Implementações | Coleções Sincronizadas
Multithreading em Java

bookConcurrentMap e Suas Implementações

Exemplo do Mundo Real

Uma aplicação web utiliza ConcurrentMap para armazenar em cache dados frequentemente requisitados, como sessões de usuário. Diferentes threads podem atualizar e ler dados do mapa simultaneamente, garantindo acesso rápido e operações seguras.

Diferenças em Relação a Outros Tipos

  • Segurança em ambiente multithread: ConcurrentMap gerencia automaticamente a sincronização dos acessos aos dados, enquanto em um Map convencional essa tarefa deve ser feita manualmente;
  • Eficiência: Permite leitura e escrita de dados em paralelo sem bloquear toda a estrutura de dados.

Implementações de ConcurrentMap

ConcurrentHashMap: Oferece suporte eficiente a múltiplas threads dividindo o mapa em segmentos (buckets), permitindo a execução paralela de operações sem bloquear todo o mapa.

Sintaxe

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap em Java divide os dados em vários baldes, cada um gerenciado por um monitor separado. Essa configuração permite que diferentes threads modifiquem ou leiam dados de baldes distintos simultaneamente, o que melhora o desempenho.

Threads podem acessar baldes em paralelo, reduzindo bloqueios e evitando condições de corrida.

Cada balde contém registros na forma de pares chave-valor, que podem ser organizados como listas encadeadas.

ConcurrentSkipListMap: Uma implementação baseada em skip-list que suporta ordenação de chaves classificadas. Proporciona inserção, exclusão e acesso a dados rápidos em um ambiente multithread.

Sintaxe

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Inserção: Ao adicionar um novo item ao ConcurrentSkipListMap, ele começa no nível mais baixo. Em seguida, sobe pelos níveis até ser posicionado onde suas chaves e valores estejam na ordem correta.

🔍Busca: Para localizar um item pela chave, o ConcurrentSkipListMap inicia no nó principal do nível mais alto. Ele segue os ponteiros até encontrar um nó com uma chave igual ou maior que a chave de busca.

❌Remoção: Para remover um item do ConcurrentSkipListMap, ele é primeiramente excluído do nível mais baixo. Depois, é rebaixado pelos níveis até ser removido de onde suas chaves e valores estejam corretamente ordenados.

Exemplo de uso do ConcurrentMap em código

Métodos principais

putIfAbsent(K key, V value): Adiciona um par chave-valor ao mapa somente se a chave ainda não estiver presente.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Remove o par chave-valor se a chave estiver associada ao valor especificado.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Substitui a entrada para uma chave somente se ela estiver atualmente associada a algum valor.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Calcula um novo valor para a chave especificada utilizando a função de remapeamento fornecida, que pode envolver criação de um novo valor, modificação ou remoção do valor existente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Mescla o valor fornecido com o valor existente associado à chave utilizando a função de remapeamento fornecida, que auxilia na agregação de dados.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) - retorna o valor associado à chave especificada ou o valor padrão caso a chave não esteja presente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Limitações

Uma das potenciais desvantagens é a instabilidade de ordem, pois algumas implementações podem não garantir a ordem dos elementos durante a iteração. Além disso, pode haver suporte limitado para certas operações; por exemplo, atualizações condicionais atômicas podem não ser totalmente suportadas em algumas implementações.

💪 Vantagens

Por outro lado, o alto desempenho é um benefício importante, tornando-o adequado para cenários que envolvem operações intensivas de leitura e escrita. Também oferece facilidade de uso, reduzindo significativamente a necessidade de gerenciamento manual de sincronização em um ambiente multithread.

1. Qual é o propósito do ConcurrentMap?

2. Qual das seguintes é uma implementação thread-safe de ConcurrentMap?

3. Como o ConcurrentHashMap garante a segurança em ambientes multithread?

question mark

Qual é o propósito do ConcurrentMap?

Select the correct answer

question mark

Qual das seguintes é uma implementação thread-safe de ConcurrentMap?

Select the correct answer

question mark

Como o ConcurrentHashMap garante a segurança em ambientes multithread?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 5

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Awesome!

Completion rate improved to 3.33

bookConcurrentMap e Suas Implementações

Deslize para mostrar o menu

Exemplo do Mundo Real

Uma aplicação web utiliza ConcurrentMap para armazenar em cache dados frequentemente requisitados, como sessões de usuário. Diferentes threads podem atualizar e ler dados do mapa simultaneamente, garantindo acesso rápido e operações seguras.

Diferenças em Relação a Outros Tipos

  • Segurança em ambiente multithread: ConcurrentMap gerencia automaticamente a sincronização dos acessos aos dados, enquanto em um Map convencional essa tarefa deve ser feita manualmente;
  • Eficiência: Permite leitura e escrita de dados em paralelo sem bloquear toda a estrutura de dados.

Implementações de ConcurrentMap

ConcurrentHashMap: Oferece suporte eficiente a múltiplas threads dividindo o mapa em segmentos (buckets), permitindo a execução paralela de operações sem bloquear todo o mapa.

Sintaxe

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap em Java divide os dados em vários baldes, cada um gerenciado por um monitor separado. Essa configuração permite que diferentes threads modifiquem ou leiam dados de baldes distintos simultaneamente, o que melhora o desempenho.

Threads podem acessar baldes em paralelo, reduzindo bloqueios e evitando condições de corrida.

Cada balde contém registros na forma de pares chave-valor, que podem ser organizados como listas encadeadas.

ConcurrentSkipListMap: Uma implementação baseada em skip-list que suporta ordenação de chaves classificadas. Proporciona inserção, exclusão e acesso a dados rápidos em um ambiente multithread.

Sintaxe

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Inserção: Ao adicionar um novo item ao ConcurrentSkipListMap, ele começa no nível mais baixo. Em seguida, sobe pelos níveis até ser posicionado onde suas chaves e valores estejam na ordem correta.

🔍Busca: Para localizar um item pela chave, o ConcurrentSkipListMap inicia no nó principal do nível mais alto. Ele segue os ponteiros até encontrar um nó com uma chave igual ou maior que a chave de busca.

❌Remoção: Para remover um item do ConcurrentSkipListMap, ele é primeiramente excluído do nível mais baixo. Depois, é rebaixado pelos níveis até ser removido de onde suas chaves e valores estejam corretamente ordenados.

Exemplo de uso do ConcurrentMap em código

Métodos principais

putIfAbsent(K key, V value): Adiciona um par chave-valor ao mapa somente se a chave ainda não estiver presente.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Remove o par chave-valor se a chave estiver associada ao valor especificado.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Substitui a entrada para uma chave somente se ela estiver atualmente associada a algum valor.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Calcula um novo valor para a chave especificada utilizando a função de remapeamento fornecida, que pode envolver criação de um novo valor, modificação ou remoção do valor existente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Mescla o valor fornecido com o valor existente associado à chave utilizando a função de remapeamento fornecida, que auxilia na agregação de dados.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) - retorna o valor associado à chave especificada ou o valor padrão caso a chave não esteja presente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Limitações

Uma das potenciais desvantagens é a instabilidade de ordem, pois algumas implementações podem não garantir a ordem dos elementos durante a iteração. Além disso, pode haver suporte limitado para certas operações; por exemplo, atualizações condicionais atômicas podem não ser totalmente suportadas em algumas implementações.

💪 Vantagens

Por outro lado, o alto desempenho é um benefício importante, tornando-o adequado para cenários que envolvem operações intensivas de leitura e escrita. Também oferece facilidade de uso, reduzindo significativamente a necessidade de gerenciamento manual de sincronização em um ambiente multithread.

1. Qual é o propósito do ConcurrentMap?

2. Qual das seguintes é uma implementação thread-safe de ConcurrentMap?

3. Como o ConcurrentHashMap garante a segurança em ambientes multithread?

question mark

Qual é o propósito do ConcurrentMap?

Select the correct answer

question mark

Qual das seguintes é uma implementação thread-safe de ConcurrentMap?

Select the correct answer

question mark

Como o ConcurrentHashMap garante a segurança em ambientes multithread?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 5
some-alt