0

I have ListIterator and within it there is list2.iterator() which throws ConcurrentModificationException when 2nd iteration goes through ListIterator

    ExecutorService executorService  = new ThreadPoolExecutor(
            1,       // Initial pool size
            1,       // Max pool size
            1,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>()
    );
    while(true){
       executorService.execute(() -> {                              
           List<String> list = Storage.list;
           for (ListIterator<String> listIterator = list.listIterator(); listIterator.hasNext(); ) {
               String s = listIterator.next();
               // string modification
               listIterator.set(s);
               List<String> list2 = Storage.list2;
               // calling list2.iterator(); on 2nd iteration of listIterator throws ConcurrentModificationException
               for (Iterator<String> iter2 = list2.iterator(); iter2 .hasNext(); ) {
                   String s2 = list2.next();
                   // no modifications of list2
               }
            }
        });
    }

list1 and list2 are created as sublist() of another List. How to avoid this exception and recreate list2 Iterator for 2nd iteration?

janusz j
  • 321
  • 3
  • 17
  • Can you show how you are modifying the list? – Sweeper Nov 18 '22 at 18:30
  • 1
    In the body of the inner loop, you are modifying `list2`. The solution is.. not to do that. CoModEx means: Something changed the underlying list during iteration. If you must, either 'cache' the changes you want to make and do them after, or use CopyOnWriteList, or make the changes on the (list)iterator (e.g. call `iterator.remove()`, do not call `list.remove(idx)`. – rzwitserloot Nov 18 '22 at 18:40
  • I am not modyfing list2, but the ConcurrentModificationException is thrown. I could use casual for each loop, but for that is also thrown ConcurrentModificationException. – janusz j Nov 18 '22 at 19:34
  • What does the body of the inner loop do? Could list2 be modified concurrently from another thread? I think we’ll need a minimal, reproducible example to be able to answer definitively. – Tim Moore Nov 18 '22 at 19:46
  • It shouldn't be and it's not. – janusz j Nov 18 '22 at 19:49
  • What is `requirementsListIterator`? It is used, but never defined in the example. – knittl Nov 18 '22 at 19:59
  • It's indeed listIterator. – janusz j Nov 18 '22 at 20:01
  • Are you sure the `while` is correct? You are nonstop and endlessly submitting tasks for execution. – xehpuk Nov 18 '22 at 21:12
  • The while is shown as example here and it was not the problem. – janusz j Nov 18 '22 at 21:13
  • You should post code that reproduces the problem, not some pseudocode. There's lots of edits and the snippet still wouldn't even compile (`list2.next()`, `Storage` is missing etc.). – xehpuk Nov 18 '22 at 21:18
  • If `list1` and `list2` are sublists, they are still backed by the original list. Modifications of any of those lists (the original and its sublists) will be seen as concurrent modification of all of those lists. – Mark Rotteveel Nov 23 '22 at 11:28

1 Answers1

0

I found solution for this I ended up extending list2.sublist(); with list recreation, adding .stream().toList(). As I don't need Iterator for this solution I exchanged it for each loop. It seems that there is problem with iteration on List created by method sublist() within ListIterator.

janusz j
  • 321
  • 3
  • 17
  • `sublist` does _not_ create a new list. It is a _view_ on the original list. Modifying the sublist will modify the original list (and vice-versa). – knittl Nov 19 '22 at 09:47
  • 2
    Using `.stream().toList()` is inefficient, use `new ArrayList(...)` to create a copy of the sublist to a new list. – Mark Rotteveel Nov 23 '22 at 11:39