Java ComputeFabSent抛出concurrentModificationException
我有一个Hashmap,在这里我维护不同类型读取器到各自java类实现的映射。我有一个多线程Java服务器,它支持32种类型的读卡器 您可以假设每30秒,每种类型的读卡器都会有1000个对象在内部调用getReader() 每当我将刷新时间减少到20秒时,它就会偶尔为一些读者抛出ConcurrentModificationException。这是预期的吗 缩短时间段有什么区别Java ComputeFabSent抛出concurrentModificationException,java,multithreading,Java,Multithreading,我有一个Hashmap,在这里我维护不同类型读取器到各自java类实现的映射。我有一个多线程Java服务器,它支持32种类型的读卡器 您可以假设每30秒,每种类型的读卡器都会有1000个对象在内部调用getReader() 每当我将刷新时间减少到20秒时,它就会偶尔为一些读者抛出ConcurrentModificationException。这是预期的吗 缩短时间段有什么区别 类映射器{ 映射读取器=新的HashMap(); 公共静态读卡器getReader(类型){ Reader=Reader
类映射器{
映射读取器=新的HashMap();
公共静态读卡器getReader(类型){
Reader=Reader.computeIfAbsent(键入,k->new ReaderImpl());
}
}
如果地图可以由多个线程访问,则应使用
每当我将刷新时间减少到20秒时,它就会偶尔为一些读者抛出ConcurrentModificationException。这是预期的吗
这可能只是巧合。如果减少时间,只会使线程更有可能尝试访问映射,并由于未使用同步收集而破坏映射。还有一种可能性是,如果您运行应用程序足够多的时间,您也可以在30秒刷新时间内获得它。调试多线程应用程序很困难,因为您可能认为您的应用程序运行正常,但最终发现,1000分之一的应用程序会出现错误,因为您处理多线程的方式错误 正如安迪·特纳(Andy Turner)正确指出的那样,您很幸运出现了
ConcurrentModificationException
。如果您没有收到任何异常,这并不意味着问题不存在。如果在生产环境中运行应用程序时收到此类错误,情况会更糟。如果多个线程可以访问地图,则应使用
每当我将刷新时间减少到20秒时,它就会偶尔为一些读者抛出ConcurrentModificationException。这是预期的吗
这可能只是巧合。如果减少时间,只会使线程更有可能尝试访问映射,并由于未使用同步收集而破坏映射。还有一种可能性是,如果您运行应用程序足够多的时间,您也可以在30秒刷新时间内获得它。调试多线程应用程序很困难,因为您可能认为您的应用程序运行正常,但最终发现,1000分之一的应用程序会出现错误,因为您处理多线程的方式错误 正如安迪·特纳(Andy Turner)正确指出的那样,您很幸运出现了
ConcurrentModificationException
。如果您没有收到任何异常,这并不意味着问题不存在。如果在生产环境中运行应用程序时收到此类错误,情况会更糟
这是预期的吗
正如(他们的强调)中所说:
请注意,此实现未同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改映射,则必须在外部对其进行同步。(结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)
至于concurrentModificationException
是否是预期的,我们不知道。应该预料的是,行为是未定义的
如果幸运的话,会发生异常。例外是好的:它们告诉你你做错了什么。如果你运气不好,它会悄悄地失败。谁知道在你的具体情况下会发生什么?也许它能正常工作,也许它不能
如果希望代码正确运行,请使用文档中的类
这是预期的吗
正如(他们的强调)中所说:
请注意,此实现未同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改映射,则必须在外部对其进行同步。(结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)
至于concurrentModificationException
是否是预期的,我们不知道。应该预料的是,行为是未定义的
如果幸运的话,会发生异常。例外是好的:它们告诉你你做错了什么。如果你运气不好,它会悄悄地失败。谁知道在你的具体情况下会发生什么?也许它能正常工作,也许它不能
如果希望代码正确运行,请使用文档中的类。使用同步映射@michalk是的,我知道ConcurrentHashMap,但这仍然不能解释为什么刷新时间为30秒时它可以工作。这可能只是巧合。如果减少时间,只会使线程更有可能尝试访问映射,并由于未使用同步收集而破坏映射。还有一种可能性是,如果您运行应用程序的时间足够长,您也可以在30秒的刷新时间内获得它。旁注:
READER
不应使用大写,因为它不是常量。永远不要依赖时间间隔来证明程序的正确性。请使用同步映射@michalk是的,我知道ConcurrentHashMap,但这仍然不能解释为什么刷新时间为30秒时它可以工作。这可能只是巧合。如果减少时间,只会使线程更有可能尝试访问映射,并由于未使用同步收集而破坏映射。如果您运行应用程序的次数足够多,也有可能出现这种情况