您现在的位置是:亿华云 > 系统运维
为什么ConcurrentHashMap不允许插入Null值?
亿华云2025-10-09 03:40:45【系统运维】2人已围观
简介在Java语言中,给ConcurrentHashMap和Hashtable这些线程安全的集合中的Key或者Value插入 null(空) 值的会报空指针异常,但是单线程操作的Ha
在Java语言中,允许给ConcurrentHashMap和Hashtable这些线程安全的插入集合中的Key或者Value插入 null(空) 值的会报空指针异常,但是允许单线程操作的HashMap又允许 Key 或者 Value 插入 null(空) 值。这到底是插入为什么呢?
1.探寻源码为了找到原因,我们先来看这样一段源码片段,允许打开ConcurrentHashMap的插入putVal()方法,源码中第一句就非常明确地做了判断,允许如果 Key 或者 Value 为 null(空) 值,插入就直接抛出空指针异常。允许
我们在源码中似乎已经找到了原因,插入你可以这样回答面试官,允许说JDK源码就是插入这么规定的。然而,允许这个原因是插入不能说服面试官的,虽然,允许源码是这样设计的,我们要思考的是,这样设计背后更深层次的原因。云南idc服务商
那到底为什么ConcurrentHashMap不允许插入 null (空)值,HashMap又允许插入呢?
2.歧义问题因为给ConcurrentHashMap中插入 null (空)值会存在歧义。我们可以假设ConcurrentHashMap允许插入 null(空) 值,那么,我们取值的时候会出现两种结果:
1)值没有在集合中,所以返回的结果就是 null (空);
2)值就是 null(空),所以返回的结果就是它原本的 null(空) 值。
这就产生了歧义问题。
那HashMap允许插入 null(空) 值,难道它就不担心出现歧义吗?这是因为HashMap的设计是给单线程使用的,所以如果取到 null(空) 值,我们可以通过HashMap的 containsKey(key)方 法来区分这个 null(空) 值到底是插入值是 null(空),还是本就没有才返回的 null(空) 值。
而 ConcurrentHashMap 就不一样了,因为 ConcurrentHashMap 是在多线程场景下使用的,免费信息发布网它的情况更加复杂。
举个例子,现在有线程T1调用了 ConcurrentHashMap 的 containsKey(key) 方法,我们期望返回的结果是false,也就是说,T1并没有往ConcurrentHashMap中 put null(空)值。
但是,恰恰出了个意外,在线程T1还没有得到返回结果之前,线程T2又调用了ConcurrentHashMap 的 put() 方法,插入了一个Key,并且存入的Value是 null(空) 值。那么,线程T1 最终得到的返回结果就变成 true 了。
显然,这个结果和我们之前期望的 false 完全不一致。
也就是说,在多线程的复杂情况下,我们多线程的复杂情况下,b2b信息网到底是插入的 null(空) 值,还是本就没有才返回的 null(空) 值。也就是说,产生的歧义不能被 证 伪,
3.作者回复对于 ConcurrentHashMap 不允许插入 null 值的问题,有人问过 ConcurrentHashMap 的作者 Doug Lea,以下是他回复的邮件内容:
The main reason that nulls arent allowed in ConcurrentMaps (ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that may be just barely tolerable in non-concurrent maps cant be accommodated. The main one is that if map.get(key) returns null, you cant detect whether the key explicitly maps to null vs the key isnt mapped.
In a non-concurrent map, you can check this via map.contains(key),but in a concurrent one, the map might have changed between calls.
Further digressing: I personally think that allowing
nulls in Maps (also Sets) is an open invitation for programs
to contain errors that remain undetected until
they break at just the wrong time. (Whether to allow nulls even
in non-concurrent Maps/Sets is one of the few design issues surrounding
Collections that Josh Bloch and I have long disagreed about.)
It is very difficult to check for null keys and values
in my entire application .
Would it be easier to declare somewhere
static final Object NULL = new Object();
and replace all use of nulls in uses of maps with NULL?
-Doug
以上信件的主要意思是,Doug Lea 认为这样设计最主要的原因是:不容忍在并发场景下出现歧义!
4.总结ConcurrentHashMap在源码中加入不允许插入 null (空) 值的设计,主要目的是为了防止并发场景下的歧义问题。
以上就是我对关于ConcurrentHashMap为什么不允许插入 null (空) 值的解答,听懂的小伙伴,请关注点个赞,下次不迷路。
很赞哦!(158)
相关文章
- 域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
- 改进博客园Markdown显示功能(加代码行号、显示代码所用编程语言)
- Python基本数据类型之字符串
- 从业务开发中学习和理解架构设计
- 6、提示添加成功,点击确认进行最后的确定操作。一般10分钟就解析生效,可以用域名进行访问了。
- 购买域名一定要找专业人士!
- 6 月数据库排行榜:Oracle、PG 和 MongoDB 分数上涨
- HTAP X 云原生: TiDB 加速释放数据价值,实现数据敏捷
- 解析之后一般在十分钟内生效,如果没有生效可以联系域名服务商进行沟通。
- 明明在InnoDB执行了delete,为啥数据删了个寂寞?
热门文章
站长推荐
域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
解决了Redis大key问题,同事们都夸他牛皮
React Native JSON解析和辅助函数(2)
执行一条 SQL 语句,期间发生了什么?
用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。
五种知名的分布式数据库大PK
原来 MySQL 索引要这么设计才能起飞
域名怎么做更好出售?