ComputeIfAbsent抛出concurrentModificationException

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

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

您可以假设每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());
    }
}

提问于
用户回答回答于

如果多个线程可以访问您的地图,则应使用ConcurrentHashMap

每当我将刷新时间减少到20秒时,它会偶尔为某些读者抛出ConcurrentModificationException。这是预期的吗?

这可能只是巧合。如果你减少了时间,你就会更有可能让Threads尝试访问地图并因为你没有使用同步集合而破坏它。如果你运行你的应用程序足够多次,你也可能在30秒的刷新时间内获得它。解决多线程应用程序很难,因为您可能认为您的应用程序运行正常 - 但最终结果表明,由于您以错误的方式处理多线程,因此1000个中的1个会出现错误。

正如安迪特纳正确指出的那样 - 你很幸运ConcurrentModificationException。如果您没有收到任何异常,并不意味着问题不在那里。如果在生产中运行时在应用程序中收到此类错误,情况会更糟。

用户回答回答于

这是预期的吗?

正如它在Javadoc中HashMap所说的那样(强调他们的):

请注意,此实现不同步。 如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。(结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)

ConcurrentModificiationException具体是否预期而言,不知道。应该期待的是行为是不确定的

如果你很幸运,会发生异常。例外是好的:他们告诉你你做错了什么。如果你不那么幸运,它会默默地失败。谁知道在您的具体情况下会发生什么?也许它会正常工作,也许它不会。

如果希望代码行为正确,请使用记录的类。

扫码关注云+社区

领取腾讯云代金券