Reputation: 916
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
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
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