Parallel List Modification Using Copy Constructor

Will the following code cause ConcurrentModificationExceptionother side effects?

ArrayList<String> newList = new ArrayList<String>(list);

Given that the size of the list is very large, and another thread at the same time changes the list when the code is executed.

+5
source share
3 answers

Edit:

My original answer is yes, but as @JohnVint correctly points out, it will not ConcurrentModificationException, as it ArrayListduplicates an array with help under covers System.arrayCopy(...). See Code Snippets at the end.

, , . IndexOutOfBoundsException, , System.arrayCopy(...) .

, , , , , ArrayList, .


public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    ...
}

// ArrayList
public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
}

// Arrays
public static <T,U> T[] copyOf(U[] original, int newLength,
    Class<? extends T[]> newType) {
    ...
    System.arraycopy(original, 0, copy, 0,
        Math.min(original.length, newLength));
}

// System
public static native void arraycopy(Object src,  int  srcPos,
    Object dest, int destPos, int length);
+8

, . list , list newList - CME . ( , CME, CME - .) : . - , , , , .

- list. , , ; , , . . , , . . , , , " ", , ...

, newList , . newList . .

- list java.util.ConcurrentLinkedQueue. ( , - .) , , , . , , , , ( , list java.util.LinkedList). newList , .

: list ArrayList, , . , ArrayList. : list . ( .) A B , newList, , , , , , . ( .) list , , , .

, , : , (, ArrayList HashTable). , , , .

, , , , . , , , . The Garbage Collector , , GC , , , , . , , 10% .

- , . . , . (, ). GC. , : LinkedList, TreeMap, ConcurrentLinkedQueue .. GC .

+1

, , @Gray. . , :

public static void main(String[] args) {

    final int n = 1000000;
    final int m = 100000;
    final ArrayList<String> strings = new ArrayList<String>(n);

    for(int i=0; i<n; i++) {
        strings.add(new String("abc"));
    }


    Thread creatorThread = new Thread(new Runnable() {
        @Override
        public void run() {
            ArrayList<String> stringsCme = new ArrayList<String>(strings);
            int wrongEntries = 0;
            for(int i=0; i<m; i++) {
                stringsCme = new ArrayList<String>(strings);

                for(String s : stringsCme) {
                    if(s == null || !s.equals("abc")) {
                        //System.out.println("Wrong entry: " + s);
                        wrongEntries++;
                    }
                }

                if(i % 100 == 0)
                    System.out.println("i = " + i + "\t list: " + stringsCme.size() + ", #wrong entries: " + wrongEntries);
            }

            System.out.println("#Wrong entries: " + wrongEntries);
        }
    });
    creatorThread.start();

    for(int i=0; i<m; i++) {
        strings.remove(MathUtils.random(strings.size()-1));
    }
}
0

All Articles