Collections.sort方法有时会在多线程环境中抛出ConcurrentModificationException.列表未在结构上进行修改

Shi*_*arg 3 java sorting collections multithreading concurrentmodification

    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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

抛出的Excption是ConcurrentModificationException,我想知道代码没有修改列表(不是结构上的).

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)
Run Code Online (Sandbox Code Playgroud)

我有返回列表最大值的方法,我不想使用Collections.max(),我想在collections.sort方法的帮助下对多线程env中的列表进行排序.

Collections.sort方法有时会在多线程环境中抛出ConcurrentModificationException.列表未在结构上进行修改.

有人可以帮我吗?

Bre*_*ken 8

您已创建单个MyRunnable实例,该实例具有ArrayList作为成员变量的实例.然后在3个单独的线程中尝试对其进行排序ArrayList.调用sort将在结构上修改列表.这就是它导致的原因ConcurrentModificationException.

  • 虽然文档不是很清楚,但排序方法也被认为是一种修改。基本上,任何改变方法内容的方法(除了 set 之外)都被视为修改。这里是jdk8的sort方法源码。您可以看到mod计数正在增加:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/ArrayList.java?av=f#1443 (2认同)