思维导图
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…