Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并发HashMap空键和并发级别_Java_Multithreading_Concurrency_Hashmap - Fatal编程技术网

Java 并发HashMap空键和并发级别

Java 并发HashMap空键和并发级别,java,multithreading,concurrency,hashmap,Java,Multithreading,Concurrency,Hashmap,请有人回答以下问题: 我理解ConcurrentHashMap中不允许null值的原因。但是为什么不允许使用null键呢 并发级别决定有多少线程可以并发访问映射,默认值为16。这意味着地图分为16个部分,每个部分都有锁。只要初始容量也是16,这就可以正常工作,因此有16个铲斗和16个锁,每个铲斗工作一个锁。 当初始容量大于并发级别时,以及初始容量小于并发级别时,这是如何工作的 为什么ConcurrentHashMaps中不允许使用null键?HashMap从Object.hash()获取其内部键

请有人回答以下问题:

  • 我理解
    ConcurrentHashMap
    中不允许
    null
    值的原因。但是为什么不允许使用
    null
    键呢

  • 并发级别决定有多少线程可以并发访问映射,默认值为16。这意味着地图分为16个部分,每个部分都有锁。只要初始容量也是16,这就可以正常工作,因此有16个铲斗和16个锁,每个铲斗工作一个锁。 当初始容量大于并发级别时,以及初始容量小于并发级别时,这是如何工作的

  • 为什么ConcurrentHashMaps中不允许使用
    null
    键?HashMap从Object.hash()获取其内部键,该值不能为空值计算。为了解决此问题,非并发哈希映射将null映射到哈希代码0。为了在
    ConcurrentHashMap
    中解决此问题,可能需要牺牲性能
  • 检查的实现:即使您尝试将initalCapacity设置为某个值,它也会进行自己的内部计算,因此这些参数只是一些提示

  • 问题1 我想支持
    null
    键通常是可能的。但这会对可读性产生影响,可能会对性能产生一些影响。后者与提供高性能多线程映射实现的目标相冲突

    问题2如果初始容量小于预期的并发级别,则初始容量将调整为访问映射的估计线程(
    initialCapacity=concurrencyLevel
    )。除此之外,并发访问
    ConcurrentHashMap
    在很大程度上与容量无关,因为线程在访问时锁定整个存储桶(更具体地说,它们锁定存储桶中的第一个元素)

    […地图分为16个部分,每个部分都有锁。只要初始容量也是16,这就可以正常工作,因此有16个铲斗和16个锁,每个铲斗工作一个锁

    为什么假设16个线程中的每一个都希望访问不同的存储桶?如果他们都想访问同一个存储桶呢

    不要把它想象成16个不同的桶,把它想象成16个完全不同的子表。散列,
    k.hashCode()
    ,不仅确定键
    k
    属于表的哪个存储桶,还确定键属于哪个子表


    如果两个线程对两个不相关的键感兴趣,
    j
    k
    ,那么这些键属于不同子表的概率为15/16,并且线程可以访问这些表而不存在争用。另1/16的时间,这是艰难的运气,其中一个线程将不得不等待;但这比它们100%碰撞的情况要好得多。

    问题1在这里得到了回答:@Keppil不,只有
    null
    values.Hmm的答案。答案的第一部分提到并发映射中的
    null
    ,但示例仅使用
    null
    作为值。然而,原始链接的答案也是关于键和值的问题,因此我将第一部分关于歧义的解释为这两个问题的原因。@Keppil如果我们有空值,您能详细说明一下歧义是什么吗key@Keppil不支持
    null
    值的参数(歧义)易于理解-与
    null
    键相比。我的猜测是,实际上没有具体的原因。
    HashMap
    允许
    null
    作为键,而
    ConcurrentHashMap
    则不允许。@Andrei我认为,OP的问题是关于设计决策:作者为什么不想要null键?很明显,如果ConcurrentHashMap的创建者希望允许null,那么NPE就有了某种解决方案。(1)
    对象。自Java7以来,hash()返回
    0
    for
    null
    @steffen
    对象
    (而不是
    对象
    )。旧版本也没有,因此必须调用
    object.hash()
    。HashMap的实现确实将null匹配到哈希键0。短语“我猜”和“可能有一点”使人不清楚这是一个答案还是一个暗中猜测。@jaco0646虽然源代码包含大量关于
    null
    值含义的注释,关于
    null
    键没有任何内容,只是它们不受支持!我认为所有关于映射键的代码都可以处理
    null
    ,特别是因为它们被包装在
    节点
    实例中。这个类包含大约6000行,我没有和作者交谈,所以我不知道他为什么决定不支持
    null
    键。因此,我想写作是我能做的最精确的事情。