1

When you have two Threads that share the same ArrayList and one thread iterates over the ArrayList while the other updates the ArrayList you can get a ConcurrentModificationException.

E.g.

Collection<Integer> coll = new ArrayList<Integer>();

Thread1 :

for(Integer i : coll){
    i++;
}

Thread2 :

coll.add(12);

My question is: are there tools which can analyse that no such errors exist in a code base? I know this means you have to be able to resolve that variables in different part of the code base refer to the same collection at runtime and it may be a hard problem to solve in general.

But I'm working on a program where it is easy to identify that the variables refer to the same Collections.

Are there analysers which can warn me of this kind of potential ConcurrentModificationException (on ArrayList, HashMap) or can you give me advice on which tool, libraries to use to check this in my specific context where I can easily see which variables are shared between threads.

I'm looking at JavaParser right now but this doesn't seem trivial.

Neuron
  • 5,141
  • 5
  • 38
  • 59
  • 2
    Not that I know of. Usually you use and create thread-safe classes once you know that you'll have concurrency. This is something you should know **ahead** of time, as it will be a lot of work to add afterwards – Neuron Nov 06 '17 at 13:38
  • 7
    There doesn't need to be such a tool because you should not share `ArrayList`s across threads. They are **not** thread safe. Use a [concurrent List implementation](https://stackoverflow.com/questions/6916385/is-there-a-concurrent-list-in-javas-jdk). – Michael Nov 06 '17 at 13:38
  • 1
    I like to think this is why we are still required in the process of code production ... we can't automate everything and some things are not easy to validate (for now...) – AxelH Nov 06 '17 at 13:43
  • ConcurrentModificationException can also happen in single-threaded environments with complex call stacks (I had that once with a lazy-loading persistence layer). Of course, careful design can avoid such problems, but that's true for all kinds of problems. So, I'd also appreciate to see a debugging tool for ConcurrentModificationExceptions – Ralf Kleberhoff Nov 06 '17 at 13:46
  • 2
    One more reason to love immutable objects. I use these wherever applicable. – Vlasec Nov 06 '17 at 13:46
  • 3
    By the way, a `ConcurrentModificationException` can be thrown simply with that code : `for(Object b : list){ list.remove(b);}` – AxelH Nov 06 '17 at 13:49
  • @LonelyNeuron please don't edit posts purely to make things `inline code` – Michael Nov 06 '17 at 13:50
  • I forgot to mention that even when you use the synchronized versions of ArrayList or HashMap you can get ConcurrentModificationException when iterating and updating on two different threads. We always use synchronized ArrayList and HashMap when shared across threads. For performance reason we don't use ConcurrentLinkedQueue. – Alain Michel Nov 06 '17 at 13:51
  • @AlainMichel CopyOnWriteArrayList is guaranteed not to: ["the iterator is guaranteed not to throw ConcurrentModificationException"](https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html). – Michael Nov 06 '17 at 13:56
  • @AlexH but it's not *necessarily* thrown by that code: https://ideone.com/tSN3fl – Andy Turner Nov 06 '17 at 13:58
  • We always use synchronized ArrayList and HashMap when shared across threads. Maybe ConcurrentLinkedQueue is the answer but right now we are stuck with code with a lot of get() and for the new code we are never 100% sure that it will be correct (we're human after all). – Alain Michel Nov 06 '17 at 14:01
  • CopyOnWriteArrayList is nice but it's costly when your list contains millions of elements. – Alain Michel Nov 06 '17 at 14:11

0 Answers0