获取ConcurrentModificationException但我没有删除

时间:2012-01-31 01:01:48

标签: java android concurrency synchronization

我使用此代码获得ConcurrentModificationException的内容是什么?我有一个synchronized(侦听器)锁。

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:致命异常:主题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:at com。 .vos.RenditionList.notifyListeners(RenditionList.java:79)   01-30 16:47:55.147 6953 6974 E AndroidRuntime:at 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 个答案:

答案 0 :(得分:5)

该异常表示可能已从另一个线程修改了侦听​​器。所以你应该检查它是否在没有同步的情况下被修改。

同时检查onRendition()的实现是否从列表中删除了侦听器,因为如果不涉及多个线程,这可能是另一个原因。

答案 1 :(得分:2)

并发有点棘手。但是,在您的应用程序的上下文中,您可能看不到您没有修改列表,但是当您调用时它会在某处被修改

l.listener.onRendition(rendition);

可能的解决方案如下。

  1. 使用ConcurrentLinkedQueue代替ArrayList。如果使用此集合,则无需编写同步块。这是最简单的解决方案。
  2. 如果1.不起作用,您可以使用CopyOnWriteArrayList代替ArrayList。当您存储侦听器时,最好使用CopyOnWriteArrayList而不是ArrayList