Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中防止偶发ConcurrentModificationException的最佳实践是什么?_Java_Thread Safety_Concurrentmodification - Fatal编程技术网

在Java中防止偶发ConcurrentModificationException的最佳实践是什么?

在Java中防止偶发ConcurrentModificationException的最佳实践是什么?,java,thread-safety,concurrentmodification,Java,Thread Safety,Concurrentmodification,在列表或映射上迭代的哪个代码序列阻止ConcurrentModificationException?我们的代码中反复出现了零星的ConcurrentModificationException。问题有两个原因 另一个线程在迭代时更改列表 循环中调用的方法正在更改列表 问题1可以通过同步循环解决。但是,如果在循环中调用外来代码(如原因2),这是不好的 问题2可以通过列表或地图的副本来解决 这意味着列表或映射必须在循环之前复制到同步块中。有更好的解决办法吗 一些示例代码: public void to

在列表或映射上迭代的哪个代码序列阻止ConcurrentModificationException?我们的代码中反复出现了零星的ConcurrentModificationException。问题有两个原因

  • 另一个线程在迭代时更改列表
  • 循环中调用的方法正在更改列表
  • 问题1可以通过同步循环解决。但是,如果在循环中调用外来代码(如原因2),这是不好的

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

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

    一些示例代码:

    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
    )。