Почему я получаю исключение ConcurrentModificationException для этого неизменяемого набора? - PullRequest
0 голосов
/ 11 ноября 2018

Я получаю исключение java.util.ConcurrentModificationException в строке, где начинается цикл for (см. Комментарий в коде).

Почему я получаю исключение ConcurrentModificationException для этого неизменяемого набора?

final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());
if (!portSet.isEmpty()) {
    StringBuilder tmpSb = new StringBuilder();
    for (Port pp : portSet) { // <------- exception happening here
        tmpSb.append(pp.getNum()).append("  ");
    }
}

Я никогда не был свидетелем этого, но я получаю отчеты о сбоях от Google.

1 Ответ

0 голосов
/ 11 ноября 2018

Что-то должно модифицировать базовый набор; то есть набор, возвращаемый node.getOpenPorts().

Вместо того, чтобы оборачивать набор «неизменяемой» оболочкой, вы можете скопировать его.

    final Set<Port> portSet = new HashSet<>(node.getOpenPorts());

Но, как отметил комментатор (@Slaw), это просто перемещает итерацию внутри конструктора, и вы все равно получите CCME.

Единственные реальные решения:

  • Измените реализацию класса узла, чтобы использовать класс параллельных наборов для списка портов, который не будет генерировать CCME, если коллекция мутирует во время ее итерации.

  • Измените реализацию класса узла, чтобы она возвращала копию списка портов. Обработайте состояние гонки при обновлении во время копирования с некоторой внутренней блокировкой.

  • Сделайте попытку / поймайте код и повторите операцию, если вы получите CCME


Я никогда не был свидетелем этого, но я получаю отчеты о сбоях от Google.

Да. Проблема возникает только в том случае, если этот код выполняется , а список открытых портов изменяется .

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