思维导图
HashMap源码:
612行:hash()方法计算了key的值
339行:当key为null时,计算出的hash值为0,value放置在第0个桶上
ConcurrentHashMap源码:
1006行:没有像HashMap一样先计算hash
1011行:先进行了判断key和value是否为null
为什么ConcurrentHashMap需要加空值校验呢?
因为存在二义性问题且ConcurrentHashMap没法解决
二义性问题
测试代码
代码分析
22行:获取test的value
23行:containsKey判断是否有test
24行:增加test和null值
25行:再次获取test的value
26行:containsKey再次判断是否有test
测试结果
结果分析
get方法获取到的value的结果都为null。所以当我们用get方法获取到一个value为null的时候,这里会产生二义性:
- 可能没有test这个key
- 可能有test这个key,只不过value为null
HashMap如何解决二义性问题
containsKey方法的结果一个为false一个为true,可以通过这个方法来区分上面说道的二义性问题
ConcurrentHashMap为什么不能解决二义性问题
因为ConcurrentHashMap是线程安全的,一般使用在并发环境下,你一开始get方法获取到null之后,再去调用containsKey方法,没法确保get方法和containsKey方法之间,没有别的线程来捣乱,刚好把你要查询的对象设置了进去或者删除掉了。
HashMap作者Doug Lea的回答
http://cs.oswego.edu/pipermai...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。