简体   繁体   English

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

[英]Creating new Object (extending Thread) results in UnsupportedOperationException when deleting from member List<E>

I have a MyObject() extends Thread which creates a new MyObject of itself in the run() method.我有一个MyObject() extends Thread ,它在run()方法中创建了一个新的MyObject This object has a List<E> as a member, where I delete from under certain conditions.这个对象有一个List<E>作为成员,我在某些条件下从中删除。

I when creating the new Object I call start() afterwards to start it's run method.我在创建新对象时调用start()以启动它的 run 方法。 But as soon as I spawn the new Object, it throws an但是一旦我生成新对象,它就会抛出一个

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

Example:例子:

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();
            }
        }
    }
}

Why do I get this error?为什么我会收到这个错误? Since the List is a member of each instance of the Object, why is it immutable for the new Threads, but not for my initial object?由于 List 是对象的每个实例的成员,为什么它对于新线程是不可变的,而对于我的初始对象却不是?

Even when you fix UnsupportedOperationException your code that removes elements from list will throw ConcurrentModificationException because you are modifying list without using iterator while traversing list using iterator即使您修复了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
    } 
}

Problem was pointed out by @Joachim Sauer: @Joachim Sauer 指出了问题:

SomeType.getList returns a List implementation that does not support structural modification (or maybe no modification at all). SomeType.getList返回一个不支持结构修改(或者根本不支持修改)的List实现。 See this question for a similar problem (with add() , but the problem source and solution is very similar).有关类似问题,请参阅问题(使用add() ,但问题来源和解决方案非常相似)。

The used list got created with List.of() which is immutable.使用的列表是用List.of()创建的,它是不可变的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM