In deze tutorial leren we met behulp van voorbeelden over de Java ConcurrentHashMap-klasse en de bewerkingen ervan.
De ConcurrentHashMap
klasse 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.ConcurrentHashMap
pakket 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 ConcurrentHashMap
klasse 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 kaartputAll()
- voegt alle gegevens van de opgegeven kaart in op deze kaartputIfAbsent()
- 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 kaartkeySet()
- geeft een set van alle sleutels van de kaart terugvalues()
- 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. Retourneertnull
als 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 kaartremove(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 entryforEachKey()
- executes the specified function for each keyforEachValue()
- 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 mappingssearchKeys()
- search function is only applied to the keyssearchValues()
- 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 functionreduceKeys()
- returns the result of gathering all the keys using the specified reducer functionreduceValues()
- 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 likeforEach()
,search()
andreduce()
.
Why ConcurrentHashMap?
- De
ConcurrentHashMap
klasse 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.