I want to sort CopyOnWriteArrayList. Currently it is throwing unsorted operation exception.
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
public static void main(final String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
list.add("3");
list.add("2");
list.add("1");
Collections.sort(list);
}
}
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.set(CopyOnWriteArrayList.java:1049)
at java.util.Collections.sort(Collections.java:159)
at com.sac.list.CopyOnWriteArrayListExample.main(CopyOnWriteArrayListExample.java:15)
Thanks in advance.
In JDK1.8 can use
sort(Comparator<? super E> c)
directly.Evgeniy's solution points in the right way, but
list.set(i, (String) a[i])
has to gain the lock onlist
for each element in the list. If there is a concurrent thread which writes intolist
this will slow down the loop dramatically.To minimize blocking it's better to reduce the number of statements which alter
list
:The downside is that if a concurrent thread reads
list
betweenclear()
andaddAll(temp)
it will see an empty list wheras with Evgeniy's solution it may see a partially sorted list.Collections.sort uses ListIterator.set
but CopyOnWriteArrayList's ListIterator does not support the remove, set or add methods.
Workaround:
Because a CopyOnWriteArrayList copies itself every time you change it, its Iterator doesn't allow you to make changes the list. If it did, the Iterator would not be thread safe, and thread safety is the whole point of this class.
Collections.sort()
won't work as it requires an Iterator that supports theset()
method.