Java ConcurrentHashMap

In deze tutorial leren we met behulp van voorbeelden over de Java ConcurrentHashMap-klasse en de bewerkingen ervan.

De ConcurrentHashMapklasse van het Java-verzamelingsraamwerk biedt een threadveilige kaart. Dat wil zeggen dat meerdere threads tegelijk toegang hebben tot de kaart zonder de consistentie van items op een kaart te beïnvloeden.

Het implementeert de ConcurrentMap-interface.

Maak een ConcurrentHashMap

Om een ​​gelijktijdige hashmap te maken, moeten we het java.util.concurrent.ConcurrentHashMappakket eerst importeren . Zodra we het pakket hebben geïmporteerd, kunnen we als volgt gelijktijdige hashmaps in Java maken.

 // ConcurrentHashMap with capacity 8 and load factor 0.6 ConcurrentHashMap numbers = new ConcurrentHashMap(8, 0.6f); 

In de bovenstaande code hebben we een gelijktijdige hashmap gemaakt met de naam numbers.

Hier,

  • Sleutel - een unieke identificatie die wordt gebruikt om elk element (waarde) in een kaart te associëren
  • Waarde - elementen die zijn gekoppeld door sleutels in een kaart

Let op het onderdeel new ConcurrentHashMap(8, 0.6). Hier is de eerste parameter capaciteit en de tweede parameter is loadFactor .

  • capaciteit - De capaciteit van deze kaart is 8. Dit betekent dat er 8 items kunnen worden opgeslagen.
  • loadFactor - De belastingsfactor van deze kaart is 0,6. Dit betekent dat wanneer onze hashtabel voor 60% gevuld is, de items worden verplaatst naar een nieuwe hashtabel die dubbel zo groot is als de originele hashtabel.

Standaard capaciteit en belastingsfactor

Het is mogelijk om een ​​gelijktijdige hashmap te maken zonder de capaciteit en belastingsfactor te definiëren. Bijvoorbeeld,

 // ConcurrentHashMap with default capacity and load factor ConcurrentHashMap numbers1 = new ConcurrentHashMap(); 

Standaard,

  • de capaciteit van de kaart zal 16 zijn
  • de belastingsfactor zal 0,75 zijn

ConcurrentHashMap maken van andere kaarten

Hier is hoe we een gelijktijdige hashmap kunnen maken die alle elementen van andere kaarten bevat.

 import java.util.concurrent.ConcurrentHashMap; import java.util.HashMap; class Main ( public static void main(String() args) ( // Creating a hashmap of even numbers HashMap evenNumbers = new HashMap(); evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); System.out.println("HashMap: " + evenNumbers); // Creating a concurrent hashmap from other map ConcurrentHashMap numbers = new ConcurrentHashMap(evenNumbers); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); ) ) 

Uitvoer

 HashMap: (Vier = 4, Twee = 2) ConcurrentHashMap: (Vier = 4, Twee = 2, Drie = 3) 

Methoden van ConcurrentHashMap

De ConcurrentHashMapklasse biedt methoden waarmee we verschillende bewerkingen op de kaart kunnen uitvoeren.

Voeg elementen toe aan ConcurrentHashMap

  • put() - voegt de opgegeven sleutel / waarde-toewijzing in op de kaart
  • putAll() - voegt alle gegevens van de opgegeven kaart in op deze kaart
  • putIfAbsent() - voegt de opgegeven sleutel / waarde-toewijzing in op de kaart als de opgegeven sleutel niet aanwezig is op de kaart

Bijvoorbeeld,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( // Creating ConcurrentHashMap of even numbers ConcurrentHashMap evenNumbers = new ConcurrentHashMap(); // Using put() evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); // Using putIfAbsent() evenNumbers.putIfAbsent("Six", 6); System.out.println("ConcurrentHashMap of even numbers: " + evenNumbers); //Creating ConcurrentHashMap of numbers ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); // Using putAll() numbers.putAll(evenNumbers); System.out.println("ConcurrentHashMap of numbers: " + numbers); ) ) 

Uitvoer

 ConcurrentHashMap van even getallen: (Six = 6, Four = 4, Two = 2) ConcurrentHashMap van getallen: (Six = 6, One = 1, Four = -4, Two = 2) 

Toegang tot ConcurrentHashMap-elementen

1. entrySet (), keySet () en values ​​() gebruiken

  • entrySet() - geeft een set terug van alle sleutel / waarde-toewijzingen van de kaart
  • keySet() - geeft een set van alle sleutels van de kaart terug
  • values() - geeft een set van alle waarden van de kaart terug

Bijvoorbeeld,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // Using entrySet() System.out.println("Key/Value mappings: " + numbers.entrySet()); // Using keySet() System.out.println("Keys: " + numbers.keySet()); // Using values() System.out.println("Values: " + numbers.values()); ) ) 

Uitvoer

 ConcurrentHashMap: (One = 1, Two = 2, Three = 3) Sleutel- / waardetoewijzingen: (One = 1, Two = 2, Three = 3) Keys: (One, Two, Three) Waarden: (1, 2, 3 ) 

2. Get () en getOrDefault () gebruiken

  • get()- Retourneert de waarde die is gekoppeld aan de opgegeven sleutel. Retourneert nullals de sleutel niet wordt gevonden.
  • getOrDefault()- Retourneert de waarde die is gekoppeld aan de opgegeven sleutel. Retourneert de opgegeven standaardwaarde als de sleutel niet wordt gevonden.

Bijvoorbeeld,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // Using get() int value1 = numbers.get("Three"); System.out.println("Using get(): " + value1); // Using getOrDefault() int value2 = numbers.getOrDefault("Five", 5); System.out.println("Using getOrDefault(): " + value2); ) ) 

Uitvoer

 ConcurrentHashMap: (One = 1, Two = 2, Three = 3) Get () gebruiken: 3 getOrDefault () gebruiken: 5 

Verwijder ConcurrentHashMap Elements

  • remove(key) - retourneert en verwijdert het item dat is gekoppeld aan de opgegeven sleutel van de kaart
  • remove(key, value) - removes the entry from the map only if the specified key mapped to the specified value and return a boolean value

For example,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // remove method with single parameter int value = numbers.remove("Two"); System.out.println("Removed value: " + value); // remove method with two parameters boolean result = numbers.remove("Three", 3); System.out.println("Is the entry (Three=3) removed? " + result); System.out.println("Updated ConcurrentHashMap: " + numbers); ) ) 

Output

 ConcurrentHashMap: (One=1, Two=2, Three=3) Removed value: 2 Is the entry (Three=3) removed? True Updated ConcurrentHashMap: (One=1) 

Bulk ConcurrentHashMap Operations

The ConcurrentHashMap class provides different bulk operations that can be applied safely to concurrent maps.

1. forEach() Method

The forEach() method iterates over our entries and executes the specified function.

It includes two parameters.

  • parallelismThreshold - It specifies that after how many elements operations in a map are executed in parallel.
  • transformer - This will transform the data before the data is passed to the specified function.

For example,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // forEach() without transformer function numbers.forEach(4, (k, v) -> System.out.println("key: " + k + " value: " + v)); // forEach() with transformer function System.out.print("Values are "); numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", ")); ) ) 

Output

 ConcurrentHashMap: (One = 1, Two = 2, Three = 3) key: One value: 1 key: Two value: 2 key: Three value: 3 Values are 1, 2, 3, 

In the above program, we have used parallel threshold 4. This means if the map contains 4 entries, the operation will be executed in parallel.

Variation of forEach() Method

  • forEachEntry() - executes the specified function for each entry
  • forEachKey() - executes the specified function for each key
  • forEachValue() - executes the specified function for each value

2. search() Method

The search() method searches the map based on the specified function and returns the matched entry.

Here, the specified function determines what entry is to be searched.

It also includes an optional parameter parallelThreshold. The parallel threshold specifies that after how many elements in the map the operation is executed in parallel.

For example,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // Using search() String key = numbers.search(4, (k, v) -> (return v == 3 ? k: null;)); System.out.println("Searched value: " + key); ) ) 

Output

 ConcurrentHashMap: (One=1, Two=2, Three=3) Searched value: Three 

Variants of search() Method

  • searchEntries() - search function is applied to key/value mappings
  • searchKeys() - search function is only applied to the keys
  • searchValues() - search function is only applied to the values

3. reduce() Method

The reduce() method accumulates (gather together) each entry in a map. This can be used when we need all the entries to perform a common task, like adding all the values of a map.

It includes two parameters.

  • parallelismThreshold - It specifies that after how many elements, operations in a map are executed in parallel.
  • transformer - This will transform the data before the data is passed to the specified function.

For example,

 import java.util.concurrent.ConcurrentHashMap; class Main ( public static void main(String() args) ( ConcurrentHashMap numbers = new ConcurrentHashMap(); numbers.put("One", 1); numbers.put("Two", 2); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); // Using search() int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2); System.out.println("Sum of all values: " + sum); ) ) 

Output

 ConcurrentHashMap: (One=1, Two=2, Three=3) Sum of all values: 6 

In the above program, notice the statement

 numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2); 

Here,

  • 4 is a parallel threshold
  • (k, v) -> v is a transformer function. It transfers the key/value mappings into values only.
  • (v1, v2) -> v1+v2 is a reducer function. It gathers together all the values and adds all values.

Variants of reduce() Method

  • reduceEntries() - returns the result of gathering all the entries using the specified reducer function
  • reduceKeys() - returns the result of gathering all the keys using the specified reducer function
  • reduceValues() - returns the result of gathering all the values using the specified reducer function

ConcurrentHashMap vs HashMap

Here are some of the differences between ConcurrentHashMap and HashMap,

  • ConcurrentHashMap is a thread-safe collection. That is, multiple threads can access and modify it at the same time.
  • ConcurrentHashMap provides methods for bulk operations like forEach(), search() and reduce().

Why ConcurrentHashMap?

  • De ConcurrentHashMapklasse staat meerdere threads toe om gelijktijdig toegang te krijgen tot de items.
  • Standaard is de gelijktijdige hashmap verdeeld in 16 segmenten . Dit is de reden waarom 16 threads tegelijkertijd de kaart mogen wijzigen. Een willekeurig aantal threads heeft echter tegelijkertijd toegang tot de kaart.
  • De putIfAbsent()methode overschrijft de invoer in de kaart niet als de opgegeven sleutel al bestaat.
  • Het biedt zijn eigen synchronisatie.

Interessante artikelen...