头图

思维导图

image.png

HashMap源码:

image.png
612行:hash()方法计算了key的值
image.png
339行:当key为null时,计算出的hash值为0,value放置在第0个桶上

ConcurrentHashMap源码:

image.png
1006行:没有像HashMap一样先计算hash
1011行:先进行了判断key和value是否为null

为什么ConcurrentHashMap需要加空值校验呢?

因为存在二义性问题且ConcurrentHashMap没法解决

二义性问题

测试代码

image.png

代码分析

22行:获取test的value
23行:containsKey判断是否有test
24行:增加test和null值
25行:再次获取test的value
26行:containsKey再次判断是否有test

测试结果

image.png

结果分析

get方法获取到的value的结果都为null。所以当我们用get方法获取到一个value为null的时候,这里会产生二义性:

  1. 可能没有test这个key
  2. 可能有test这个key,只不过value为null

HashMap如何解决二义性问题

containsKey方法的结果一个为false一个为true,可以通过这个方法来区分上面说道的二义性问题

ConcurrentHashMap为什么不能解决二义性问题

因为ConcurrentHashMap是线程安全的,一般使用在并发环境下,你一开始get方法获取到null之后,再去调用containsKey方法,没法确保get方法和containsKey方法之间,没有别的线程来捣乱,刚好把你要查询的对象设置了进去或者删除掉了。

HashMap作者Doug Lea的回答

http://cs.oswego.edu/pipermai...

幻想的绝望
1 声望0 粉丝

在绝望中追寻