I'm modifying same list from multiple threads, shouldn't it trigger ConcurrentModificationException while iterating list?
What could be done to trigger this exception?
public class ConcurrentTest {
static List<String> list = setupList();
public static List<String> setupList() {
System.out.println("setup predefined list");
List<String> l = new ArrayList();
for(int i = 0; i < 50;i++) {
l.add("test" + i);
}
return l;
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(50);
for(int i = 0; i < 50; i++) {
executorService.submit( () -> {
list.add("key1");
Thread currentThread = Thread.currentThread();
System.out.println( Thread.currentThread().getName() + ", " + list.size() );
for(String val: list) {
try {
Thread.sleep(25);
}
catch(Exception e) {
}
}
});
}
executorService.shutdown();
}
}
Your code does (and can) produce a ConcurrentModificationException
. You are not catching it to print it.
With the below, we can see that it indeed throws many ConcurrentModificationException
.
try {
for (String val : list) {
try {
Thread.sleep(25);
} catch (Exception e) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
NOTE: From the javadoc,
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 {@code 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
Also see: java.util.ConcurrentModificationException not thrown when expected
Or, you could get the returned Future
and collect them in a list. By doing that, you will get the exception when calling get
on (atleast) one of the futures.