Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreaded library exposing unsafe ArrayList

I am using a shared library in Java that returns ArrayList; as I iterate over it, a ConcurrentModificationException could be thrown and I am looking for 100% (?) guarantee to be safe. I was thinking on something like below and I'd appreciate any input.

The data_list is the ArrayList<> returned from the MT library.

boolean pass = true;

ArrayList<Something> local = new ArrayList<Something>(256);

for (int spin=0; spin<10; ++spin)
{
  try {
    local.addAll(data_list);
  }
  catch (java.util.ConcurrentModificationException ce) {
    pass = false;
  }
  finally {
    if (pass) break;
    pass = true;
  }
}

Assuming variable pass is true, how should I operate on local?

like image 396
Basixp Avatar asked Jul 01 '13 18:07

Basixp


1 Answers

There is no safe way to do this. You should not catch ConcurrentModificationException.

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

Some collections, like HashMap, even can enter an infinite loop when used this way. Here's an explanation of how it happens.

You should not do this. There is no correct way to do this.

Either you misunderstand how the library works, or you need to switch out your library with one written by a competent developer.

What library are you using?

like image 142
Steven Schlansker Avatar answered Nov 04 '22 00:11

Steven Schlansker