从成员列表中删除时,创建新对象(扩展线程)会导致unsupportedoperationexception< e>

1rhkuytd  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(348)

我有一个 MyObject() extends Thread 创造了一个新的 MyObject 在这个世界上 run() 方法。此对象具有 List<E> 作为一个成员,在某些条件下我从中删除。
我在创建我调用的新对象时 start() 然后启动它的run方法。但我一产生新对象,它就会抛出一个

Exception in thread "Thread-1" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:73)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.remove(ImmutableCollections.java:80)
at mypackage.MyMainClass.MyObject.run(MyObject.java:87)  <- here I remove from my List

例子:

public class MyObject extends Thread {
    List<SomeType> list = new ArrayList<SomeType>();
    SomeType st;

    public MyObject(SomeType st) {
        this.st = st;
        // returns a List of SomeType
        list = st.getList();
    }

    @Override
    public void run() {
        while(!done) {
            SomeType toDelete;
            if (condition) {
                toDelete = st.getToDelete();
            }
            // Checks for null etc are done and not important
            for (SomeType sometype : list) {
                if (somecondition) {
                    // toDelete is always in that List
                    list.remove(toDelete)
                } 
            }

            if (lastcondition) {
                MyObject newObject = new MyObject(this.st);
                newObject.start();
            }
        }
    }
}

为什么会出现这个错误?既然列表是对象的每个示例的成员,为什么它对新线程是不可变的,而对我的初始对象是不可变的?

bihw5rsg

bihw5rsg1#

即使你修好了 UnsupportedOperationException 从列表中删除元素的代码将引发 ConcurrentModificationException 因为您在使用迭代器遍历列表时不使用迭代器修改列表

for (SomeType sometype : list) { // this creates iterator behind the scene
    if (somecondition) {
        // toDelete is always in that List
        list.remove(toDelete); // this modifies the list and makes iterator throw ConcurrentModificationException
    } 
}
llycmphe

llycmphe2#

问题由@joachim sauer指出: SomeType.getList 返回一个 List 不支持结构修改(或者根本不支持修改)的实现。有关类似问题,请参见此问题(使用 add() ,但问题的来源和解决方法非常相似)。
已用列表是用 List.of() 这是不变的。

相关问题