“This is the fifth day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
In the Java language, thread-safe collections such as ConcurrentHashMap and Hashtable do not allow keys or values to be inserted into null values, while HashMap allows keys or values to be inserted into null values. Why is that?
Null value insertion demonstration
Insert a null value into the HashMap as follows:
HashMap<String, Object> map = new HashMap();
// Insert a null value
map.put(null.null);
if (map.containsKey(null)) {
System.out.println("There is null");
} else {
System.out.println("There is no NULL");
}
Copy the code
The execution results of the above procedures are as follows:As you can see from the above results, a HashMap allows keys or values to be inserted with null values. We then try to insert null values into the key and value of ConcurrentHashMap in the same way:No error was reported during compilation. The above program was executed and the results were as follows:ConcurrentHashMap cannot be used to insert null values. Otherwise, the program will report a null pointer exception during runtime.
PS: The use of Hashtable is similar to that of ConcurrentHashMap, which will not be demonstrated here.
ConcurrentHashMap source code analysis
To find out what caused the error, we tried to open the source code for ConcurrentHashMap. Open ConcurrentHashMap add element method put implementation source code as follows:NullPointerException = null; NullPointerException = null; NullPointerException = null
Explore the ultimate cause
ConcurrentHashMap does not allow null values to be inserted. However, this reason does not convince the interviewer that the source code is designed this way, but we need to consider the deeper reason behind this design. Why does ConcurrentHashMap not allow null insertion? Why does HashMap allow null insertions?
Ambiguity problem
The so-called ambiguity problem refers to unclear or ambiguous meaning. We assume that ConcurrentHashMap allows the insertion of NULL, then there is an ambiguity problem, which has two meanings:
- Value is not in the collection, so null is returned.
- The value is null, so the original null value is returned.
As you can see, this is the ambiguity of ConcurrentHashMap, so why is HashMap not afraid of ambiguity?
A falsifiable HashMap
HashMap is not immune to ambiguity. Why? This is because HashMap is designed for single-thread use, so if a null value is found, we can use the hashmap.containskey (key) method to tell whether the null value is stored. Or null, which doesn’t exist? This solves the ambiguity problem, so HashMap is not afraid of it.
Unfalsifiable ConcurrentHashMap
ConcurrentHashMap, however, is more complicated because it uses multithreaded scenarios. We assume that the ConcurrentHashMap can be deposited in the null values, there is such A scenario, there is now A thread calls A ConcurrentHashMap. Either containsKey (key), we expect the returned result is false, But before we call concurrentHashMap. Either containsKey (key), did not return a result before thread B again call concurrentHashMap. Put (key, null) in the null values, Thread A will return true, which is completely different from the false we expected. In other words, the multithreading situation is so complicated that there is no way to determine whether a null value returned at any given moment is null, or if it does not exist at all. This is why ConcurrentHashMap is designed in the source code. Eliminate ambiguity when key or value is null.
Answer by ConcurrentHashMap designer
ConcurrentHashMap does not allow nulls to be inserted. Doug Lea, author of ConcurrentHashMap, responded to this email by asking:
The main reason that nulls aren’t allowed in ConcurrentMaps (ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that may be just barely tolerable in non-concurrent maps can’t be accommodated. The main one is that if map.get(key) returns null, you can’t detect whether the key explicitly maps to null vs the key isn’t mapped. In a non-concurrent map, you can check this via map.contains(key),but in a concurrent one, the map might have changed between calls. Further digressing: I personally think that allowing nulls in Maps (also Sets) is an open invitation for programs to contain errors that remain undetected until they break at just the wrong time. (Whether to allow nulls even in non-concurrent Maps/Sets is one of the few design issues surrounding Collections that Josh Bloch and I have long disagreed about.)
It is very difficult to check for null keys and values in my entire application .
Would it be easier to declare somewhere static final Object NULL = new Object(); and replace all use of nulls in uses of maps with NULL? -Doug
The main point of the above letter is that Doug Lea believes the main reason for this design is to not tolerate ambiguity in concurrent scenarios!
conclusion
Concurrent collections such as ConcurrentHashMap or Hashtable do not allow null values for keys or values. This is implemented directly at the JDK source level, and is designed to prevent ambiguity in concurrent scenarios.
Reference documentation
www.cnblogs.com/fanguangdex…
Judge right and wrong from yourself, praise to listen to others, gain and loss in the number.
Public number: Java interview analysis
Interview collection: gitee.com/mydb/interv…