开发者社区> 问答> 正文

为什么哈希映射不应在多线程环境中使用?

和Java语言的特点有关吗?

展开
收起
YDYK 2020-04-25 21:03:52 572 0
2 条回答
写回答
取消 提交回答
  • 技术架构师 阿里云开发者社区技术专家博主 CSDN签约专栏技术博主 掘金签约技术博主 云安全联盟专家 众多开源代码库Commiter

    key value映射的过程,对于key来说是不重复的,如果多线程环境同时操作了一个key。就会出现问题

    2020-04-25 23:35:24
    赞同 展开评论 打赏
  • 我们知道,这是非同步集合,因为它的同步反部分是。因此,当您在多线程环境中访问集合并且所有线程都访问单个集合实例时,由于各种明显的原因(例如,为了避免脏读和保持数据一致性)使用它更安全。在最坏的情况下,这种多线程环境也会导致无限循环。HashMapHashTableHashTable

    是的,这是真的。 可以引起无限循环。让我们看看怎么做?HashMap.get()

    如果查看源代码HashMap.get(对象键)方法,如下所示:

    public Object get(Object key) { Object k = maskNull(key); int hash = hash(k); int i = indexFor(hash, table.length); Entry e = table[i]; while (true) { if (e == null) return e; if (e.hash == hash && eq(k, e.key)) return e.value; e = e.next; } } while(true){...}在多线程环境中运行时,在运行时,始终可以成为无限循环的受害者,IF,不知何故可以指向自身。这将导致无限循环。但是,如何指向自己(即)。e.nexte.next

    这可能发生在方法中,该方法在调整大小时调用。void transfer(Entry[] newTable)HashMap

    do { Entry next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); 如果进行调整大小,同时其他线程尝试修改映射实例,则此代码容易产生上述条件。

    避免这种情况的唯一方法是在代码中使用同步,或者更好地使用同步集合。

    2020-04-26 10:03:50
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载

相关实验场景

更多