【发布时间】:2013-09-26 06:30:04
【问题描述】:
影响HashMap性能的初始容量和负载因子两个参数。
默认负载因子 (.75) 在时间和空间成本之间提供了良好的折衷。较高的值会减少空间开销,但会增加查找成本。
当一个项目被添加到HashMap 时,它会根据其hashCode 的派生值和HashMap 的桶大小分配给一个桶。
要识别任意的桶,Hash map 使用key.hashCode() 并执行一些操作:
Bucket (index) = HashMap.indexFor(HashMap.hash(key.hashCode()),
entryArray.length)
当哈希图中的条目数超过负载因子和当前容量的乘积时,哈希图被重新哈希(内部数据结构被重建),使得哈希图大约有两倍的桶数。
当您重新哈希并将所有内容移动到新位置(存储桶等)时,旧元素也会再次重新哈希并根据其新哈希码存储在新存储桶中。分配用于存储元素的旧空间被垃圾回收。
如果两个线程同时发现现在HashMap 需要重新调整大小并且他们都尝试重新调整大小可能会导致HashMap 中的竞争条件。
在重新调整HashMap 大小的过程中,存储在链表中的bucket 中的元素在迁移到新bucket 期间会按顺序颠倒,因为java HashMap 不会将新元素附加到tail它在头部附加新元素以避免尾部遍历。如果发生竞态条件,那么您将最终陷入无限循环。
我有以下问题:
- 为什么每个bucket的链表在运行过程中是按顺序颠倒的 迁移到新存储桶?
- 竞态条件如何导致无限循环?
- 增加存储桶数量如何减少查找等待 时间?
- 在同一个桶中的元素仍然会在同一个桶中 重新散列后存储桶?
【问题讨论】:
-
您的帖子是一组问题,不符合问答概念:单个问题和答案可以客观地选择最佳。
-
您从哪里获得所有这些信息?我在 JDK 6 源代码中看不到任何证据,我必须提供最新的源代码。
-
1.如果将单链表从一个存储桶转移到另一个存储桶,则它会更快。把它想象成一个栈,你从栈 1 弹出,推到栈 2,
O(1)操作。虽然附加到 SLL 是O(n) -
3.使用链接时的查找速度是
O(m),其中m是平均桶大小。 -
您的问题 +1。也许你现在得到了正确的答案。但我也面临同样的困惑。我找到了下面的链接。看看:mailinator.blogspot.hu/2009/06/beautiful-race-condition.html
标签: java