Создание нового объекта (расширяющего потока) приводит к исключению UnsupportedOperationException при удалении из списка членов <E> - PullRequest
2 голосов
/ 24 января 2020

У меня есть MyObject() extends Thread, который создает новый MyObject самого себя в методе run(). Этот объект имеет List<E> в качестве члена, из которого я удаляюсь при определенных условиях.

I при создании нового объекта, который я вызываю 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();
            }
        }
    }
}

Почему я получаю эту ошибку? Поскольку список является членом каждого экземпляра объекта, почему он неизменен для новых потоков, а не для моего начального объекта?

Ответы [ 2 ]

1 голос
/ 28 января 2020

Даже если вы исправите 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
    } 
}
0 голосов
/ 24 января 2020

Проблема была указана @Joachim Sauer:

SomeType.getList возвращает реализацию List, которая не поддерживает структурную модификацию (или, возможно, вообще никакой модификации). См. этот вопрос для аналогичной проблемы (с add(), но источник проблемы и решение очень похожи).

Используемый список создан с List.of(), который неизменны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...