• Java中的ConcurrentHashMap中为什么不能存储null?


    众所周知,在Java中Map可以存储null,而ConcurrentHashMap不能存储null值,那么为什么呢?

    一、先出源码出发

    在这里插入图片描述
    put方法点进去~
    在这里插入图片描述

    @throws NullPointerException if the specified key or value is null and this map does not permit null keys or values

    可以清晰的看到源码中规定,ConcurrentHashMap是不可以存储null值的。

    二、那么究竟这是为什么呢?

    可以先具体的了解一下ConcurrentHashMap。

    与HashMap一样,ConcurrentHashMap也是一个基于散列的Map,但它使用了一种完全不同的加锁策略来提供更高的并发性和伸缩性。ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是使用一种更细的加锁机制来实现更大程度的共享,这种机制成为分段锁。在这种机制中,任意数量的读取线程可以并发地访问Map,执行读取操作的线程和执行写入操作的线程可以并发地访问Map,并且一定数量的写入线程可以并发地修改Map。ConcurrentHashMap带来的结果是,在并发访问环境下将实现更高的吞吐量,而在单线程环境中只损失非常小的性能。

    ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及时失败”。弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以在迭代器被构造后将修改操作反映给容器。ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及时失败”。弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以在迭代器被构造后将修改操作反映给容器。

    三、ConcurrentHashMap 作者 Doug Lea 的邮件

    对于 ConcurrentHashMap 不允许插入 null 值的问题,有人问过 ConcurrentHashMap 的作者 Doug Lea,以下是他回复的邮件内容:

    The main reason that nulls aren’t allowed in ConcurrentMaps
    (ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that
    may be just barely tolerable in non-concurrent maps can’t be
    accommodated. The main one is that if map.get(key) returns null, you
    can’t detect whether the key explicitly maps to null vs the key isn’t
    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
    allowingnulls in Maps (also Sets) is an open invitation for programsto
    contain errors that remain undetected untilthey break at just the
    wrong time. (Whether to allow nulls evenin non-concurrent Maps/Sets is
    one of the few design issues surroundingCollections that Josh Bloch
    and I have long disagreed about.)It is very difficult to check for
    null keys and valuesin my entire application .Would it be easier to
    declare somewherestatic final Object NULL = new Object();and replace
    all use of nulls in uses of maps with NULL?

    -Doug

    以上信件的主要意思是,Doug Lea 认为这样设计最主要的原因是:不容忍在并发场景下出现歧义!

  • 相关阅读:
    K8S LoadBalancer kube-vip 部署
    农场管理小程序|基于微信小程序的农场管理系统设计与实现(源码+数据库+文档)
    【随想】闲聊、沟通和谈判
    【论文阅读】Whisper: Robust Speech Recognition via Large-Scale Weak Supervision
    1356:计算(calc)
    Momentum Safe 启动大使计划,大家积极参与进来,让我们的社区越来越壮大
    广州蓝景分享—程序员在面试时必须要做的五件事,最后一件很重要
    关于Copy On Write Array List,你会安全使用么
    测试管理的知识和讨论总结
    k8s自动化安装脚本(二进制)
  • 原文地址:https://blog.csdn.net/guorui_java/article/details/125343592