ConcurrentHashMap为什么key和value不能为null

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的时候,这里会产生二义性:

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

HashMap如何解决二义性问题

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

public boolean containsKey(Object key) {
    return getNode(hash(key), key) != null;
}
  • 如果存在key为null的元素(key=null对应的hash值=0),getNode获取到值不为null;
  • 如果不存在key为null的元素,此时hash值=0对应的下标元素为null,即getNode获取到的值为null;

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

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

HashMap作者Doug Lea的回答

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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值