简体   繁体   English

ComputeIfAbsent引发并发ModificationException

[英]ComputeIfAbsent throwing concurrentModificationException

I have a Hashmap where I maintain mapping of different kinds of readers to their respective java class implementations. 我有一个Hashmap,在其中维护不同类型的读者到它们各自的java类实现的映射。 I have a multithreaded Java server which supports 32 types of readers. 我有一个支持32种类型的阅读器的多线程Java服务器。

You can assume every 30 seconds, getReader() is called internally by 1000s of objects for each type of reader. 您可以假设每30秒对每种类型的阅读器在内部由1000个对象调用getReader()。

Whenever I reduce the refresh time to 20 seconds, it starts throwing ConcurrentModificationException for some readers sporadically. 每当我将刷新时间减少到20秒时,它就会偶尔为某些读者引发ConcurrentModificationException。 Is it expected? 是预期的吗?

What difference does it make with decreasing the time period? 减少时间间隔有什么不同?

class Mapper {
    Map<String, Reader> READER = new HashMap<>();

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

You should use a ConcurrentHashMap if your map can be accessed by multiple Threads. 如果您的地图可以被多个线程访问,则应该使用ConcurrentHashMap

Whenever I reduce the refresh time to 20 seconds, it starts throwing ConcurrentModificationException for some readers sporadically. 每当我将刷新时间减少到20秒时,它就会偶尔为某些读者引发ConcurrentModificationException。 Is it expected? 是预期的吗?

It might be just coincidence. 可能只是巧合。 If you reduce the time you just make it more probable that Threads will try to access the map and will break it because you are not using synchronized collection. 如果减少时间,则只是使线程更有可能尝试访问该映射并将其破坏,因为您没有使用同步集合。 There is also possibility that if you run your application enough times you will get it also for your 30 seconds refresh time. 如果您的应用程序运行足够的时间,您也有可能在30秒钟的刷新时间内获得它。 Debuging multithreaded applications is hard because you might think that your application is running okay - but in the end it turns out that for 1 out of 1000 you get an error because you handled multithreading the wrong way. 调试多线程应用程序很困难,因为您可能认为您的应用程序运行正常-但最终结果是,每1000个错误中有1个错误,因为您以错误的方式处理了多线程。

As Andy Turner pointed out correctly - you are lucky that ConcurrentModificationException appeared. 正如Andy Turner正确指出的那样-您很幸运出现了ConcurrentModificationException If you receive no exception that does not mean the problem is not there. 如果您没有收到任何例外情况,这并不意味着问题就不存在。 It would be worse if you received such error in your application when running in production. 如果在生产环境中运行时在应用程序中收到此类错误,情况将更糟。

Is it expected? 是预期的吗?

As it says in the Javadoc of HashMap (emphasis theirs): 就像在HashMapJavadoc中所说的(强调他们的):

Note that this implementation is not synchronized. 请注意,此实现未同步。 If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. 如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改该映射,则必须在外部进行同步。 (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已经包含的键相关联的值不是结构修改。)

In terms of whether a ConcurrentModificiationException specifically is expected, don't know. 就是否特别需要ConcurrentModificiationException而言,尚不清楚。 What should be expected is that the behaviour is undefined . 应该预期的是, 行为是不确定的

If you're lucky, an exception occurs. 如果幸运的话,会发生异常。 Exceptions are good: they tell you you're doing something wrong. 例外很好:它们告诉您您做错了什么。 If you're less lucky, it silently fails. 如果您不那么幸运,它会自动失败。 Who knows what will happen in your specific circumstances? 谁知道在您的特定情况下会发生什么? Maybe it will work correctly, maybe it doesn't. 也许它将正常运行,也许不能。

If you want your code to behave correctly, use the classes as they are documented. 如果您希望代码正常运行,请使用已记录的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 抛出ConcurrentModificationException系统依赖 - Is throwing ConcurrentModificationException system dependent Eclipselink抛出ConcurrentModificationException - Eclipselink throwing ConcurrentModificationException Hibernate抛出ConcurrentModificationException - Hibernate throwing a ConcurrentModificationException 双端队列删除未引发ConcurrentModificationException - Deque remove is not throwing ConcurrentModificationException 为什么此代码引发ConcurrentModificationException? - Why is this code throwing a ConcurrentModificationException? 列表抛出 ConcurrentModificationException 传递给 CompletableFutures - List throwing ConcurrentModificationException passed to CompletableFutures Hibernate抛出带有嵌入式ElementCollection的ConcurrentModificationException - Hibernate throwing ConcurrentModificationException with an embedded ElementCollection 由于 Java 9 HashMap.computeIfAbsent() 在尝试记住递归函数结果时抛出 ConcurrentModificationException - Since Java 9 HashMap.computeIfAbsent() throws ConcurrentModificationException on attempt to memoize recursive function results 遍历集合以添加项目但抛出 ConcurrentModificationException - Iterating through collections to add items but throwing ConcurrentModificationException 并发修改异常 - concurrentModificationException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM