Shiva Garg
Shiva Garg

Reputation: 916

Collections.sort method sometimes throws ConcurrentModificationException in multithreaded environment . List is not being modified structurally

    package CollectionsTS;

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.List;

    public class ArrayListTS {
        public static void main(String[] args) {
            HashSet<Integer> hset = new HashSet<Integer>();
            for (int i = 0; i <= 1000; i++) {
                hset.add(i);
            }

            MyRunnable mr = new MyRunnable();
            mr.addElements(hset);

            Thread t1 = new Thread(mr,"t1");
            Thread t2 = new Thread(mr,"t2");
            Thread t3 = new Thread(mr,"t3");

            t1.start(); t2.start(); t3.start();

        }
    }

    class MyRunnable implements Runnable {

        List<Integer> ilist = new ArrayList<Integer>();

        public void addElements(HashSet<Integer> hset) {
            ilist.addAll(hset);
        }

        @Override
        public void run() {
            Collections.sort(ilist);
            if (ilist.size() > 0)
                System.out.println( Thread.currentThread().getName() +" = "+ilist.get(ilist.size() - 1));
            else
                System.out.println("List is empty");
        }
    }

Excption thrown is ConcurrentModificationException , I am wondering the code is not modifying the list (not structurally) .

Exception in thread "t1" t3 = 1000
Exception in thread "t2" java.util.ConcurrentModificationException
    at java.util.ArrayList.sort(Unknown Source)
    at java.util.Collections.sort(Unknown Source)
    at CollectionsTS.MyRunnable.run(ArrayListTS.java:37)
    at java.lang.Thread.run(Unknown Source)
java.util.ConcurrentModificationException
    at java.util.ArrayList.sort(Unknown Source)
    at java.util.Collections.sort(Unknown Source)
    at CollectionsTS.MyRunnable.run(ArrayListTS.java:37)
    at java.lang.Thread.run(Unknown Source)

I have method which returns the maximum out of list , I don't want to usr Collections.max() , I want to sort the list in multithreaded env with help of collections.sort method.

Collections.sort method sometimes throws ConcurrentModificationException in multithreaded environment . List is not being modified structurally.

Could anyone help me on this ?

Upvotes: 9

Views: 10457

Answers (2)

Kaushik Mandal
Kaushik Mandal

Reputation: 21

This is due to fact that Collections.sort() was changed in java 8.0_20. There's an in-depth article about it here. Contrary to the old Collections.sort, this implementation modifies the modCount of the collection once the list has been sorted, even if the structure itself didn’t really change (still the same number of elements).

So it will do an internal change even if the collection is already sorted, whereas before that change it didn't do that. That's why you're getting an exception now.

The actual fix is to not to sort a collection using multiple threads at the same time. You shouldn't do that.

Upvotes: 2

Brett Okken
Brett Okken

Reputation: 6306

You have created a single MyRunnable instance, which has an ArrayList as a member variable. Then in 3 separate threads you attempt to sort the ArrayList. Calling sort will structurally modify the list. That is why it results in a ConcurrentModificationException.

Upvotes: 12

Related Questions