首先看到这个问题,肯定先打开源码看一眼
可以发现调用putVal的时候如果key或者value为null,那么就会抛出一个空指针异常。
但是,为什么不允许使用null呢?
答案是:为了避免在多线程环境下出现歧义问题。
所谓的歧义问题就是:我们再调用get方法获取对应的value的时候,如果返回的结果是null,我们是没有办法判断它是put(k,v)的时候v本身是null,还是这个key本身就不存在。
比如如下情况:
如果Thread1线程先执行containsKey方法,那么由于这个key不存在,那么就会返回false,而如果是Thread2先执行put方法,那么Thread1再次执行containsKey就会返回true,那么此时返回的结果就根据两个线程的执行顺序决定了,就会产生歧义,这就算一个线程安全问题,而ConcurrenrtHashMap要求线程安全,而对于HashMap就不需要关心这一点,因为它本身就没有考虑线程安全这一设计。
答案:
ConcurrentHashMap这么设计的原因是为了避免再多线程并发这一场景下出现歧义问题。也就是说在一个线程试图去ConcurrentHashMap中获取key的情况下,如果返回的结果是null,那么不能判断是由于这个key本身不存在导致的null,或者说是value的值本身就是null这一歧义问题。那么这种情况就会导致线程安全问题,而ConcurrentHashMap它本身就是一个基于线程安全设计的集合,所以才会这么设计,不允许null键值。