在Java中防止偶发ConcurrentModificationException的最佳实践是什么?
在列表或映射上迭代的哪个代码序列阻止ConcurrentModificationException?我们的代码中反复出现了零星的ConcurrentModificationException。问题有两个原因在Java中防止偶发ConcurrentModificationException的最佳实践是什么?,java,thread-safety,concurrentmodification,Java,Thread Safety,Concurrentmodification,在列表或映射上迭代的哪个代码序列阻止ConcurrentModificationException?我们的代码中反复出现了零星的ConcurrentModificationException。问题有两个原因 另一个线程在迭代时更改列表 循环中调用的方法正在更改列表 问题1可以通过同步循环解决。但是,如果在循环中调用外来代码(如原因2),这是不好的 问题2可以通过列表或地图的副本来解决 这意味着列表或映射必须在循环之前复制到同步块中。有更好的解决办法吗 一些示例代码: public void to
public void todoSomeThings( Map<Abc, Object> map ){
for( Abc abc : map.keySet() ){
abc.todoSomeThings();
}
}
public void todosmethings(地图){
for(Abc:map.keySet()){
abc.todoSomeThings();
}
}
您是否考虑过在中使用并发集合?老实说,很难给出比这更好的建议。。。我们需要更多的细节
注意的一点是,如果您在线程之间共享了可变的集合,以及在您迭代时暴露了太多代码的可变集合,您不知道在迭代过程中可能会发生什么变化,那么如果可能的话,您可能需要考虑更改设计。不可变的集合通常可以保持事物的整洁,有时(但并非总是)以牺牲一些性能为代价。一开始使用它们可能会比较困难,但之后您可能会发现更容易对代码进行推理。
您考虑过在中使用并发集合吗?老实说,很难给出比这更好的建议。。。我们需要更多的细节注意的一点是,如果您在线程之间共享了可变的集合,以及在您迭代时暴露了太多代码的可变集合,您不知道在迭代过程中可能会发生什么变化,那么如果可能的话,您可能需要考虑更改设计。不可变的集合通常可以保持事物的整洁,有时(但并非总是)以牺牲一些性能为代价。它们一开始可能更难处理,但您可能会发现以后更容易对代码进行推理。
一个合理的警告:使用j.u.c(java.util.concurrent)将删除错误,但您可能会遇到更糟糕的情况,即争用更新、过时读取等。最佳做法是了解您的数据结构,使用状态。。。或者至少(这不是最好的)使用锁。一个合理的警告:使用j.u.c(java.util.concurrent)将删除错误,但您可能会遇到更糟糕的情况,即争用更新、过时读取等。最佳做法是
了解您的数据结构,使用状态。。。或者至少(这不是最好的)使用锁。在大多数情况下,列表或映射的类型是不可能更改的,因为它是一个参数。@Horcrux7:这是一个很好的例子,说明了为什么方法应该尽可能采用通用参数(例如
list
而不是ArrayList
)。在大多数情况下,无法更改列表或映射的类型,因为它是一个参数。@Horcrux7:这是一个很好的例子,说明了为什么方法应尽可能采用常规参数(例如,list
而不是ArrayList
)。