问题
What is the use of ConcurrentHashMap
in Java? What are its benefits? How does it work?
Sample code would be useful too.
回答1:
The point is to provide an implementation of HashMap
that is threadsafe. Multiple threads can read from and write to it without the chance of receiving out-of-date or corrupted data. ConcurrentHashMap
provides its own synchronization, so you do not have to synchronize accesses to it explicitly.
Another feature of ConcurrentHashMap
is that it provides the putIfAbsent
method, which will atomically add a mapping if the specified key does not exist. Consider the following code:
ConcurrentHashMap<String, Integer> myMap = new ConcurrentHashMap<String, Integer>();
// some stuff
if (!myMap.contains("key")) {
myMap.put("key", 3);
}
This code is not threadsafe, because another thread could add a mapping for "key"
between the call to contains
and the call to put
. The correct implementation would be:
myMap.putIfAbsent("key", 3);
回答2:
ConcurrentHashMap
allow concurrent access to the map. HashTables too offers synchronized access to map, but your entire map is locked to perform any operation.
The logic behind ConcurrentHashMap is that your entire table is not getting locked
, but only the portion[segments
]. Each segments manages its own HashTable. Locking is applied only for updates. In case of of retrievals, it allows full concurrency.
Let's take four threads are concurrently working on a map whose capacity is 32, the table is partitioned into four segments where each segments manages a hash table of capacity. The collection maintains a list of 16 segments by default, each of which is used to guard (or lock on) a single bucket of the map.
This effectively means that 16 threads can modify the collection at a single time. This level of concurrency can be increased using the optional concurrencyLevel constructor argument.
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel)
As the other answer stated, the ConcurrentHashMap offers new method putIfAbsent()
which is similar to put except the value will not be overridden if the key exists.
private static Map<String,String> aMap =new ConcurrentHashMap<String,String>();
if(!aMap.contains("key"))
aMap.put("key","value");
The new method is also faster as it avoids double traversing
as above. contains
method has to locate the segment and iterate the table to find the key and again the method put
has to traverse the bucket and put the key.
回答3:
Really the big functional difference is it doesn't throw an exception and/or end up corrupt when someone else changes it while you're using it.
With regular collections, if another thread adds or removes an element while you're access it (via the iterator) it will throw an exception. ConcurrentHashMap lets them make the change and doesn't stop your thread.
Mind you it does not make any kind of synchronization guarantees or promises about the point-in-time visibility of the change from one thread to the other. (It's sort of like a read-committed database isolation, rather than a synchronized map which behaves more like a serializable database isolation. (old school row-locking SQL serializable, not Oracle-ish multiversion serializable :) )
The most common use I know of is in caching immutable derived information in App Server environments where many threads may be accessing the same thing, and it doesn't really matter if two happen to calculate the same cache value and put it twice because they interleave, etc. (e.g., it's used extensively inside the Spring WebMVC framework for holding runtime-derived config like mappings from URLs to Handler Methods.)
回答4:
It can be used for memoization:
import java.util.concurrent.ConcurrentHashMap;
public static Function<Integer, Integer> fib = (n) -> {
Map<Integer, Integer> cache = new ConcurrentHashMap<>();
if (n == 0 || n == 1) return n;
return cache.computeIfAbsent(n, (key) -> HelloWorld.fib.apply(n - 2) + HelloWorld.fib.apply(n - 1));
};
回答5:
1.ConcurrentHashMap is thread-safe that is the code can be accessed by single thread at a time .
2.ConcurrentHashMap synchronizes or locks on the certain portion of the Map . To optimize the performance of ConcurrentHashMap , Map is divided into different partitions depending upon the Concurrency level . So that we do not need to synchronize the whole Map Object.
3.Default concurrency level is 16, accordingly map is divided into 16 part and each part is governed with a different lock that means 16 thread can operate.
4.ConcurrentHashMap does not allow NULL values . So the key can not be null in ConcurrentHashMap .
回答6:
Hello guys today we discussed the ConcurrentHashMap.
What is ConcurrentHashMap?
ConcurrentHashMap is a class it introduce in java 1.5 which implements the ConcurrentMap as well as the Serializable interface. ConcurrentHashMap is enhance the HashMap when it dealing with multiple Theading. As we know when the application has multiple threading HashMap is not a good choice because performance issue occurred.
There are the some key point of ConcurrentHashMap.
- Underling data structure for ConcurrentHashMap is HashTable.
- ConcurrentHashMap is a class, That class is thread safe, it means multiple thread can access on a single thread object without any complication.
- ConcurretnHashMap object is divided into number of segment according to the concurrency level.
- The Default Concurrency-level of ConcurrentHashMap is 16.
- In ConcurrentHashMap any number of Thread can perform the retrieval operation,But for updation in object Thread must lock the particular Segment in which thread want to operate.
- This type of locking mechanism is known as Segment-Locking OR Bucket-Locking.
- In ConcurrentHashMap the 16 updation operation perform at a time.
- Null insertion is not possible in ConcurrentHashMap.
Here are the ConcurrentHashMap construction.
ConcurrentHashMap m=new ConcurrentHashMap();:Creates a new, empty map with a default initial capacity (16), load factor (0.75) and concurrencyLevel (16).
ConcurrentHashMap m=new ConcurrentHashMap(int initialCapacity);:Creates a new, empty map with the specified initial capacity, and with default load factor (0.75) and concurrencyLevel (16).
ConcurrentHashMap m=new ConcurrentHashMap(int initialCapacity, float loadFactor);: Creates a new, empty map with the specified initial capacity and load factor and with the default concurrencyLevel (16).
ConcurrentHashMap m=new ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel);:Creates a new, empty map with the specified initial capacity, load factor and concurrency level.
ConcurrentHashMap m=new ConcurrentHashMap(Map m);:Creates a new map with the same mappings as the given map.
ConcurretHashMap has one method named is putIfAbsent(); That method is prevent to store the duplicate key please refer the below example.
import java.util.concurrent.*;
class ConcurrentHashMapDemo {
public static void main(String[] args)
{
ConcurrentHashMap m = new ConcurrentHashMap();
m.put(1, "Hello");
m.put(2, "Vala");
m.put(3, "Sarakar");
// Here we cant add Hello because 1 key
// is already present in ConcurrentHashMap object
m.putIfAbsent(1, "Hello");
// We can remove entry because 2 key
// is associated with For value
m.remove(2, "Vala");
// Now we can add Vala
m.putIfAbsent(4, "Vala");
System.out.println(m);
}
}
来源:https://stackoverflow.com/questions/2836267/concurrenthashmap-in-java