ConcurrentModificationException only in Java 1.8.0_45

I have two questions about this code:

import java.util.*;

public class TestClass {

    private static List<String> list;   
    public static void main(String[] argv) {

        list = generateStringList(new Random(), "qwertyuioasdfghjklzxcvbnmPOIUYTREWQLKJHGFDSAMNBVCXZ1232456789", 50, 1000);

//      Collections.sort(list, new Comparator<String>() {
//          public int compare(String f1, String f2) {
//              return -f1.compareTo(f2);
//          }
//      });

        for (int i = 0; i < 500; i++) {
            new MyThread(i).start();
         }

    }

    private static class MyThread extends Thread  {
        int id;
        MyThread(int id) { this.id = id; }
        public void run() {

            Collections.sort(list, new Comparator<String>() {
                public int compare(String f1, String f2) {
                    return -f1.compareTo(f2);
                }
            });

            for (Iterator it = list.iterator(); it.hasNext();) {
                String s = (String) it.next();
                try {
                    Thread.sleep(10 + (int)(Math.random()*100));
                }catch (Exception e) { e.printStackTrace(); }

                System.out.println(id+" -> "+s);
            }           
        }       
    }

    public static List<String> generateStringList(Random rng, String characters, int length, int size)
    {
        List<String> list = new ArrayList<String>();
        for (int j = 0; j < size; j++) {
            char[] text = new char[length];
            for (int i = 0; i < length; i++)
            {
                text[i] = characters.charAt(rng.nextInt(characters.length()));
            }
            list.add(new String(text));
        }
        return list;
    }
}

Running this code in java 1.8.0_45 I got java.util.ConcurrentModificationException.

1) Why did I get an exception, also, if I decompress the sort before thread.start?

2) Why did I get only an exception from java 1.8.0_45? At 1.6.0_45, 1.7.0_79, 1.8.0_5 it works fine.

+4
source share
4 answers

@nbokmans already nailed the common reason why you get this exception. However, it is true that this is version dependent. I will write why you get this in java 8.0_45, but not 1.6.0_45, 1.7.0_79, 1.8.0_5.

, Collections.sort() java 8.0_20. . , , :

public void sort(Comparator<? super E> c) {
  final int expectedModCount = modCount;
  Arrays.sort((E[]) elementData, 0, size, c);
  if (modCount != expectedModCount) {
    throw new ConcurrentModificationException();
  }
  modCount++;
}

:

Collections.sort modCount ( 7 ), , ( ).

, , , . .

+7

A ConcurrentModificationException , ( ) , .

, , , () .

ConcurrentModificationException javadoc:

, , . undefined .

500 , .

# sort MyThread #run().

+3

Java 8 Collections::sort List::sort. , , . , ArrayList , LinkedList .

ArrayList::sort , .

Java 8 Collections::sort . , . :

public static <T> void sort(List<T> list, Comparator<? super T> c) {
    Object[] a = list.toArray();
    Arrays.sort(a, (Comparator)c);
    ListIterator i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set(a[j]);
    }
}

Arrays::sort. , . ListIterator.

ArrayList, ArrayList , , . , , . , , Collections::sort.

ArrayList, , . , Java 8, . Java 8, , , .

+2

, , .

. CME . , CME. Java.

It seems that your threads do not need to change the list, so you can sort once before the loop that creates the threads, and then delete if from the stream.

0
source

Source: https://habr.com/ru/post/1608497/


All Articles