Concurrent Modification exception

前端 未结 9 1363
谎友^
谎友^ 2020-11-22 14:36

I have this little piece of code and it gives me the concurrent modification exception. I cannot understand why I keep getting it, even though I do not see any concurrent mo

相关标签:
9条回答
  • 2020-11-22 15:13

    ConcurrentModificationException may arise in both single threaded environment and multi-threaded environment. The main catch is that all the general purpose iterators (like the one used in ArrayList) are all FailFast iterators, which fails when we try to modify one list if one iterator is already iterating over it. Solution - > Use CopyOnWriteArrayList if such scenario is needed by the requirement rather than using ArrayList.

    For a complete demo for this, below mentioned code can be used. We just need to change the implementation from CopyOnWriteArrayList to ArrayList.

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    /**
     * @author narif
     *
     */
    public class TestApp {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            List<String> testList = new ArrayList<>();
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add("abc");
            testList.add(6, "abcAtindex6");
            int size = testList.size();
            System.out.println("The Current List (ArrayList) is: " + testList);
            System.out.println("The size of the List (ArrayList) is: " + size);
            /* Comment the below lines to get the ConcurrentModificationException */
            testList = new CopyOnWriteArrayList<>(testList);
            for (String value : testList) {
                System.out.println("The Value from ForEach Loop is: " + value);
                /*
                 * Concurrent modification is happening here
                 * One iterator is iterating over the list while we are trying to add new values to
                 * the list so the results of the iteration are undefined under these circumstances.
                 * So teh fail fast iterators will fail and will throw the ConcurrentModificationException.
                 */
                testList.add("valueFromForLoop");
                testList.add("anotherValueFromForEachLoop");
            }
            Iterator<String> it = testList.iterator();
            while (it.hasNext()) {
                String abc = it.next();
                System.out.println(abc);
                testList.add("Value from Iterator1");
                testList.add("Value from Iterator2");
                testList.add("Value from Iterator3");
                testList.add("Value from Iterator4");
    
            }
            System.out.println("Did the modificationa and all after conevrting the ArrayList to CopyOnWriteArrayList.");
            System.out.println("Calling the method to get the new List..");
            testList = new CopyOnWriteArrayList<>(getTheList(testList));
            for (String value : testList) {
                System.out.println("The value returned from method is : " + value);
            }
        }
    
        private static List<String> getTheList(List<String> pList) {
            List<String> list = new CopyOnWriteArrayList<>(pList);
            int i = 0;
            for (String lValue : list) {
                System.out.println("The list Passed is " + list);
                i++;
                list.add("localVaueFromMethod" + i);
                list.removeAll(pList);
            }
            return list;
        }
    
    }
    

    For more inifo follow this link this may be helpful alot ConcurrentModificationException Java Docs

    0 讨论(0)
  • 2020-11-22 15:14

    From the JavaDoc: for ConcurrentModificatoinException: "it is not generally permssible for one thread to modify a Collection while another thread is iterating over it".

    It simply means that if you still have an open iterator, you aren't allowed to modify the list because the iterator loop will break. Try moving ListIterator<String> it = s.listIterator(); till after the for loop.

    0 讨论(0)
  • 2020-11-22 15:14

    Have a look at oracle documentation page.

    public class ConcurrentModificationException
    extends RuntimeException
    

    This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible

    Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

    In your case, you have modified the collection after creating the iterator and hence you have encountered the exception.

    If you change your code as per Stephen C answer, you won't get this error.

    0 讨论(0)
提交回复
热议问题