首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发访问中的HashMap挂起

并发访问中的HashMap挂起
EN

Stack Overflow用户
提问于 2016-08-04 07:37:28
回答 2查看 1.1K关注 0票数 1

我们有一个应用程序,它使用了一个java.util.HashMap实例,该实例是通过不同的间接方向共享的,因此多个线程可以并发地访问它。我们现在已经修复了这个问题,因为我们知道java.util.HashMap不是线程安全的,不应该并发访问。

在修复之前,以及我们发现的原因之前,我们对JDK进行了升级(升级到IBM 7 SR3),在升级之后,我们在HashMap实例的get操作中偶尔遇到挂起(挂起发生在getEntry()方法中)。

出于好奇,我想知道,HashMap内部发生了什么,是什么导致了吊死。影响并发访问行为的实现有什么不同?

关于HashMap实现,IBM与Oracle和OpenJDK相同,这也与Java8版本(使用Node数据结构)不同。

我相信,java7u40 b43与b147的区别代表了随着升级而引入的变化。

我目前的假设是,挂起的原因与addEntry方法中的变化有关,从加先调整后更改到调整大小先加后。

但是,有没有人有一个确切的理解,究竟在并发访问过程中发生了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-11 07:01:13

最后,我调试了我们编写的单元测试,并在线程挂起/循环时检查了HashMap的桶。实际上,当两个线程同时调整映射大小时,它们会在桶中创建一个循环。它最终形成了这样的结构:

代码语言:javascript
复制
bucket1[0].entry1.next = entry2;
bucket1[0].entry2.next = entry1;

更详细的解释可以在这里找到调整HashMap大小:前方的危险

票数 0
EN

Stack Overflow用户

发布于 2016-08-11 07:23:58

当调用hashmap.put(键,值)时,将检查HashMap阈值。如果映射大小超过此阈值,映射将被调整大小,所有条目将被重新散列。

在多线程环境中,这将使HashMap处于不一致的状态。至少,您应该通过使用同步或锁来保护应用程序中写入HashMap的调用。

我建议使用java.util.concurrent.ConcurrentHashMap。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38761222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档