1

哪个用于迭代列表或映射的代码序列可防止 ConcurrentModificationException?我们的代码中有反复和零星的 ConcurrentModificationException。问题有 2 个原因。

  1. 另一个线程在迭代时更改列表
  2. 在循环中调用的方法正在更改列表。

问题 1 可以通过同步循环来解决。但是,如果像原因 2 一样在循环中调用外星代码,那就不好了。

问题 2 可以通过列表或地图的副本来解决。

这意味着列表或映射必须在循环之前复制到同步块中。有更好的解决方案吗?

一些示例代码:

public void todoSomeThings( Map<Abc, Object> map ){
    for( Abc abc : map.keySet() ){
        abc.todoSomeThings();
    }
}
4

2 回答 2

7

您是否考虑过在 中使用并发集合java.util.concurrent?老实说,很难给出比这更好的建议……我们需要更多细节。

需要注意的一点是,如果您在线程之间共享可变集合,并且可变集合暴露给您的大量代码,以至于您不知道在迭代时可能会发生什么变化,那么您可能需要考虑如果可能的话,改变你的设计。不可变集合通常可以使事情保持清洁,有时(但不总是)以牺牲一些性能为代价。一开始它们可能更难使用,但之后您可能会发现更容易推理您的代码。

于 2011-01-11T07:53:25.493 回答
3

一个公平的警告:使用 juc (java.util.concurrent) 将删除错误,但您可能会遇到更糟糕的情况,即竞争更新、过时读取等。最佳做法是

了解您的数据结构,使用状态......或者至少(这不是最好的)使用锁。

于 2011-01-11T10:12:26.590 回答