我有一个Hashmap,我在其中维护不同类型的读取器到它们各自的java类实现的映射。我有一个支持32种读卡器的多线程Java服务器。
您可以假设每隔30秒,getReader()就会被每种类型的读取器的1000个对象内部调用。
每当我将刷新时间减少到20秒时,它就开始零星地向一些读取器抛出ConcurrentModificationException。这是意料之中的吗?
减少时间段有什么不同?
class Mapper {
Map<String, Reader> READER = new HashMap<>();
public static Reader getReader(type) {
Reader reader = READER.computeIfAbsent(type, k -> new ReaderImpl());
}
}
发布于 2019-06-04 03:28:15
是预期的吗?
注意,这个实现是不同步的。指出,如果多个线程并发地访问一个散列映射,并且至少有一个线程在结构上修改了映射,那么它必须是外部同步的。(结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)
至于是否特别期望ConcurrentModificiationException
,我不知道。应该预料到的是,行为是未定义的。
如果你够幸运,一个异常就会发生。
如果您希望代码正确运行,请按照文档中的说明使用这些类。
发布于 2019-06-04 03:07:00
如果你的地图可以被多个线程访问,你应该使用一个ConcurrentHashMap。
每当我将刷新时间减少到20秒时,它就开始零星地为一些读取器抛出ConcurrentModificationException。这是意料之中的吗?
这可能只是巧合。如果您减少了时间,那么线程更有可能尝试访问映射并将其破坏,因为您没有使用同步集合。还有一种可能是,如果你运行应用程序的次数足够多,你也会在30秒的刷新时间内得到它。调试多线程应用程序是很困难的,因为您可能认为您的应用程序运行正常-但最终发现,1000个应用程序中有1个会出现错误,因为您以错误的方式处理了多线程。
正如安迪·特纳所指出的那样-- ConcurrentModificationException
的出现是你的幸运。如果您没有收到异常,这并不意味着问题不存在。如果在生产环境中运行时在应用程序中收到这样的错误,情况会更糟。
https://stackoverflow.com/questions/56433061
复制相似问题