首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ComputeIfAbsent抛出concurrentModificationException

ComputeIfAbsent抛出concurrentModificationException
EN

Stack Overflow用户
提问于 2019-06-04 02:55:00
回答 2查看 176关注 0票数 1

我有一个Hashmap,我在其中维护不同类型的读取器到它们各自的java类实现的映射。我有一个支持32种读卡器的多线程Java服务器。

您可以假设每隔30秒,getReader()就会被每种类型的读取器的1000个对象内部调用。

每当我将刷新时间减少到20秒时,它就开始零星地向一些读取器抛出ConcurrentModificationException。这是意料之中的吗?

减少时间段有什么不同?

代码语言:javascript
复制
class Mapper {
    Map<String, Reader> READER = new HashMap<>();

    public static Reader getReader(type) {
        Reader reader = READER.computeIfAbsent(type, k -> new ReaderImpl());
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-04 03:28:15

是预期的吗?

注意,这个实现是不同步的。指出,如果多个线程并发地访问一个散列映射,并且至少有一个线程在结构上修改了映射,那么它必须是外部同步的。(结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)

至于是否特别期望ConcurrentModificiationException,我不知道。应该预料到的是,行为是未定义的。

如果你够幸运,一个异常就会发生。

如果您希望代码正确运行,请按照文档中的说明使用这些类。

票数 2
EN

Stack Overflow用户

发布于 2019-06-04 03:07:00

如果你的地图可以被多个线程访问,你应该使用一个ConcurrentHashMap

每当我将刷新时间减少到20秒时,它就开始零星地为一些读取器抛出ConcurrentModificationException。这是意料之中的吗?

这可能只是巧合。如果您减少了时间,那么线程更有可能尝试访问映射并将其破坏,因为您没有使用同步集合。还有一种可能是,如果你运行应用程序的次数足够多,你也会在30秒的刷新时间内得到它。调试多线程应用程序是很困难的,因为您可能认为您的应用程序运行正常-但最终发现,1000个应用程序中有1个会出现错误,因为您以错误的方式处理了多线程。

正如安迪·特纳所指出的那样-- ConcurrentModificationException的出现是你的幸运。如果您没有收到异常,这并不意味着问题不存在。如果在生产环境中运行时在应用程序中收到这样的错误,情况会更糟。

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

https://stackoverflow.com/questions/56433061

复制
相关文章

相似问题

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