简体   繁体   中英

What is the best practice to prevent a sporadic ConcurrentModificationException in Java?

Which code sequence for iterating over a list or map prevent ConcurrentModificationException? We have repeatedly and sporadic ConcurrentModificationException in our code. There are 2 causes for the problem.

  1. Another thread change the list on iterating
  2. A method which is called in the loop is changing the list.

Problem 1 can be solved with a synchronized around the loop. But this is bad if alien code is called in the loop like cause 2.

Problem 2 can be solved with a copy of the list or map.

This means the list or map must be copy in a synchronized block before the loop. Are there a better solution?

Some sample code:

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

Have you considered using the concurrent collections in java.util.concurrent ? It's hard to give much better advice than that, to be honest... we'd need more details.

One point to note is that if you've got mutable collections shared between threads, and mutable collections exposed to so much of your code that you don't know what might be mutating it while you're iterating, then you might want to consider changing your design if possible. Immutable collections can often keep things cleaner, sometimes (but not always) at the cost of some performance. They can be harder to work with to start with, but you're likely to find it easier to reason about your code afterwards.

A fair warning: using juc (java.util.concurrent) will remove the errors but you will be running into possibly worse case, ie race updates, stale reads, etc. The best practice is

Know your data structures, use states... or at least (which is not best) use locks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM