Получение ConcurrentModificationException, но я не удаляю - PullRequest
0 голосов
/ 31 января 2012

Что я получу ConcurrentModificationException с этим кодом?У меня есть синхронизированная блокировка (слушателей).

private void notifyListeners(MediumRendition rendition) {
    if (rendition == null) return;
    synchronized (listeners) {
        for (RenditionEventListener l : listeners) {
            if (l.renditionType.equals(rendition.getType()) && l.mediumId == rendition.getMediumId()) {
                l.listener.onRendition(rendition);
            }
        }
    }
}

public void put(String renditionType, long mediumId, MediumRendition rendition) {
    HashMap<Long, MediumRendition> l = list.get(renditionType);
    if (l == null) {
        l = new HashMap<Long, MediumRendition>();
        list.put(renditionType, l);
    }
    l.put(mediumId, rendition);
    notifyListeners(rendition);
}

public void addRenditionListener(String renditionType, long mediumId, RenditionListener listener) {
    synchronized (listeners) {
        listeners.add(new RenditionEventListener(renditionType, mediumId, listener));
    }
}

01-30 16: 47: 55,147 6953 6974 E AndroidRuntime: FATAL EXCEPTION: Thread 1 01-30 16: 47: 55.147 6953 6974 E AndroidRuntime: java.util.ConcurrentModificationException 01-30 16: 47: 55.147 6953 6974 E AndroidRuntime: at java.util.ArrayList $ ArrayListIterator.next (ArrayList.java:573) 01-30 16: 47: 55.147 6953 6974 E AndroidRuntime: в com. .vos.RenditionList.notifyListeners (RenditionList.java:79) 01-30 16: 47: 55.147 6953 6974 E AndroidRuntime: в com.t .vos.RenditionList.put (RenditionList.java:41) 01-30 16:47:55.147 6953 6974 E AndroidRuntime: at com. *. Controllers.OmwController $ 6.run (OmwController.java:212)

решено: очевидно, я удаляю.Смотри ниже.

Ответы [ 2 ]

5 голосов
/ 31 января 2012

Исключение указывает, что слушатели могли быть изменены из другого потока. Поэтому вам следует проверить, не изменяется ли он без синхронизации где-либо еще.

Также проверьте, удаляет ли реализация onRendition () прослушиватель из списка, поскольку это может быть другой причиной, если не задействованы несколько потоков.

2 голосов
/ 31 января 2012

Параллелизм довольно сложен.Однако в контексте вашего приложения вы можете не видеть, что вы не изменяете список, но он где-то изменяется, когда вы звоните

l.listener.onRendition(rendition);

Возможные решения приведены ниже.

  1. Используйте ConcurrentLinkedQueue вместо ArrayList.Вам не нужно писать блок синхронизации, если вы используете эту коллекцию.Это самое простое решение.
  2. Если 1. не работает, вы можете использовать CopyOnWriteArrayList вместо ArrayList.Когда вы прячете слушателей, предпочтительнее использовать CopyOnWriteArrayList вместо ArrayList.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...