[英]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): 就像在
HashMap
的Javadoc中所说的(强调他们的):
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.