ConcurrentHashMap
在ConcurrentHashMap 的源码,在 put 方法里面,可以看到这样一段代码,如果 key 或者 value 为空,则抛出空指针异常。
但是为什么 ConcurrentHashMap 不允许 key 或者 value 为空呢?
原因
简单来说,就是为了避免在多线程环境下出现歧义问题。所谓歧义问题,就是如果 key 或者 value 为 null,当我们通过 get(key)获取对应的 value的时候,如果返回的结果是 null我们没办法判断,它是 put(k,v)的时候,value 本身为 null 值,还是这个 key 本身就不存在。比如在这样一种情况下(如图),线程 t1 调用 containsKey 方法判断 key 是否存在,假设当前这个 key 不存在,本来应该返回 false。但是在 T1 线程返回之前,正好有一个 T2 线程插入了这个 key,但是 value 为null。这就导致原本 T1 线程返回的结果有可能是 true,有可能是 false,取决于 T1 和 T2 线程的执行顺序。
总结
这种现象我们可以认为是线程安全性问题,而 ConcurrentHashMap 又是一个线程安全的集合,
所以自然就不允许 key 或者 value 为 null。而 HashMap 中是允许存 null 的,因为它不需要考虑到线程安全性问题。所以这个问题的核心本质还是 ConcurrentHashMap 这个并发安全性集合的特性。当然。Doug Lea 还认为,不管是否是并发安全的集合,它都不应该允许存储 null。