English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
在本教程中,我们将借助示例学习Java ConcurrentHashMap类及其操作。
Java集合框架的ConcurrentHashMap类提供了线程安全的映射。也就是说,多个线程可以一次访问该映射,而不会影响映射中条目的一致性。
它继承了ConcurrentMap接口。
为了创建并发的哈希图,我们必须先导入java.util.concurrent.ConcurrentHashMap包。导入包后,就可以在Java中创建并发哈希映射。
//ConcurrentHashMap具有容量8和负载因子0.6 ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
在上面的代码中,我们创建了一个名为numbers的并发哈希映射。
Aqui,
Chave - 用于关联map中每个元素(值)的唯一标识符
Value - map中与键相关联的元素
注意语句 new ConcurrentHashMap<>(8, 0.6)。在这里,第一个参数是capacity,第二个参数是loadFactor。
capacity -该映射的容量为8。意味着,它可以存储8个条目。
loadFactor-此map的负载因子为0.6。这意味着,只要我们的哈希表填充了60%,条目就会移到新哈希表中,其大小是原始哈希表的两倍。
默认容量和负载因子
无需定义其容量和负载因子就可以创建并发哈希图。例如,
// 具有默认容量和负载因子的ConcurrentHashMap ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
Padrão,
A capacidade do map será 16
O fator de carga será 0.75
Isso é como criamos um ConcurrentHashMap que contém todos os elementos de outro mapeamento.
import java.util.concurrent.ConcurrentHashMap; import java.util.HashMap; class Main { public static void main(String[] args) { // Criando HashMap de números pares HashMap<String, Integer> evenNumbers = new HashMap<>(); evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); System.out.println("HashMap: " + evenNumbers); //Criando ConcurrentHashMap a partir de outro mapeamento ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); } }
Resultados de saída
HashMap: {Four=4, Two=2} ConcurrentHashMap: {Four=4, Two=2, Three=3}
A classe ConcurrentHashMap fornece métodos que permitem que executemos várias operações no mapeamento.
put() - Insira a chave especificada/Valores mapeados são inseridos no mapeamento
putAll() - Insira todos os itens do mapeamento especificado neste map
putIfAbsent() - Se o mapeamento não contiver a chave especificada, insira a chave/Valores mapeados são inseridos no map
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { //Criando ConcurrentHashMap de números pares ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>(); // Usando put() evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); // Usando putIfAbsent() evenNumbers.putIfAbsent("Six", 6); System.out.println("ConcurrentHashMap de números pares: " + evenNumbers); //Criando ConcurrentHashMap de números ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); // Usando putAll() numbers.putAll(evenNumbers); System.out.println("ConcurrentHashMap de números pares: " + numbers); } }
Resultados de saída
ConcurrentHashMap de números pares: {Six=6, One=4, Two=2} ConcurrentHashMap的数字为: {Six=6O número do ConcurrentHashMap é: {Six=1, One=-4, Two=2}
1acessar elementos do ConcurrentHashMap
.usando entrySet(), keySet() e values() - entrySet()/retorna um conjunto de todas as chaves
coleção de mapeamento de valores - keySet()
retorna a coleção de todas as chaves do map - values()
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // retorna a coleção de todos os valores do map usando entrySet()/Mapeamento de valores: " + numbers.entrySet()); // usando keySet() System.out.println("Chaves: " + numbers.keySet()); // usando values() System.out.println("Valores: " + numbers.values()); } }
Resultados de saída
ConcurrentHashMap: {One=1, Two=2, Three=3} Chave/Mapeamento de valores: [One=1, Two=2, Three=3] Chaves: [One, Two, Three] Valores: [1, 2, 3]
2.usando get() e getOrDefault()
get() - retorna o valor associado à chave especificada. Se a chave não for encontrada, retorna null.
getOrDefault() - retorna o valor associado à chave especificada. Se a chave não for encontrada, retorna o valor padrão especificado.
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // usando get() int value1 = numbers.get("Three"); System.out.println("usando get(): " + value1); // usando getOrDefault() int value2 = numbers.getOrDefault("Five", 5); System.out.println("usando getOrDefault(): " + value2); } }
Resultados de saída
ConcurrentHashMap: {One=1, Two=2, Three=3} usando get(): 3 usando getOrDefault(): 5
remove(key) - retorna e remove a entrada associada à chave especificada do mapeamento
remove(key, value) - apenas quando a chave mapeada para o valor especificado estiver presente no mapeamento e o valor booleano retornado for true, a entrada será removida do mapeamento
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); //método de exclusão com um parâmetro int value = numbers.remove("Two"); System.out.println("Valor excluído: " + value); // método de exclusão com dois parâmetros boolean result = numbers.remove("Three", 3); System.out.println("Item {Three=3} foi removido? " + result); System.out.println("ConcurrentHashMap atualizado: ", + numbers); } }
Resultados de saída
ConcurrentHashMap: {One=1, Two=2, Three=3} Valor removido: 2 Item {Three=3} foi removido? True ConcurrentHashMap atualizado: {One=1}
A classe ConcurrentHashMap oferece métodos de operação em lote diferentes que podem ser aplicados de forma segura a mapas paralelos.
O método forEach() percorre nossos itens e executa a função especificada.
Ela contém dois parâmetros.
parallelismThreshold -Ela especifica quantos elementos de operação paralela devem ser executados no mapeamento.
transformer -Isso convertirá os dados antes de passar para a função especificada.
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); //forEach() não contém a função passada numbers.forEach(4, (k, v) -> System.out.println("chave: ", + k + " valor: " + v)); // forEach() passa a função especificada System.out.print("Valores são "); numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + , "); } }
Resultados de saída
ConcurrentHashMap: {One = 1, Two = 2, Three = 3} chave: One valor: 1 chave: Two valor: 2 chave: Three valor: 3 Valores são 1, 2, 3,
No programa acima, usamos o limiar paralelo4. Isso significa que, se o mapeamento contiver4Se houver vários itens, a operação será executada em paralelo.
Variante do método forEach()
forEachEntry() - Executa a função especificada para cada entrada
forEachKey() - Executa a função especificada para cada chave
forEachValue() - Executa a função especificada para cada valor
O método search() pesquisa o map com base na função especificada e retorna o item correspondente.
Aqui, a função especificada determina o que será pesquisado.
Ele também contém um parâmetro opcional parallelThreshold. O limiar paralelo especifica quantos elementos após o mapeamento para executar a operação em paralelo.
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // usando search() String key = numbers.search(4, (k, v) -> {return v == 3 ? k: null;}); System.out.println("Valor pesquisado: ", + key); } }
Resultados de saída
ConcurrentHashMap: {One=1, Two=2, Three=3} O valor a ser pesquisado: Three
Variações do método search()
searchEntries() - A função de busca é aplicada às chaves/Mapeamento de valores
searchKeys() - A função de busca é aplicada apenas às chaves
searchValues() - A função de busca é aplicada apenas aos valores
O método reduce() acumula (agrega) cada entrada no mapeamento. Quando precisamos de todas as entradas para executar uma tarefa comum (por exemplo, somar todos os valores do mapeamento), podemos usar este método.
Ela contém dois parâmetros.
parallelismThreshold -Ela especifica quantos elementos após isso, a operação no map será executada em paralelo.
transformer - Isso convertirá os dados antes de passar para a função especificada.
Por exemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // usando search() int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2); System.out.println("A soma de todos os valores: " + sum); } }
Resultados de saída
ConcurrentHashMap: {One=1, Two=2, Three=3} A soma de todos os valores: 6
Neste programa, note as seguintes sentenças
numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2);
Aqui,
4 É o limiar paralelo
(k, v) -> v é uma função de conversão. Ela converte a chave/A mapeamento de valores apenas se converte em valores.
(v1, v2) -> v1+v2 É uma função de cálculo de tamanho. Ela coleta todos os valores e soma todos os valores.
Variação do método reduce()
reduceEntries() - Retorna o resultado de coletar todos os itens usando a função reducer especificada
reduceKeys() - Retorna o resultado de coletar todos os valores usando a função reducer especificada
reduceValues() - retornar o resultado de coletar todos os valores usando a função reducer especificada
A seguir estão ConcurrentHashMap eHashMapalgumas diferenças entre
ConcurrentHashMap éthread-safeconjunto. Isso significa que várias threads podem acessá-lo e modificá-lo ao mesmo tempo.
ConcurrentHashMap fornece métodos para operações em lote, como forEach(), search() e reduce().
a classe ConcurrentHashMap permite que várias threads realizem operações de modificação concorrentes.
por padrão, o mapeamento hash concorrente é dividido em16seções. Isso é por que permite16por que várias threads modificam o mapeamento ao mesmo tempo. No entanto, uma quantidade arbitrária de threads pode acessar uma vez.
Se a chave especificada já existir, o método putIfAbsent() não cobrirá a entrada no mapeamento.