Java 获取ConcurrentModificationException,但我';我不会搬走的

Java 获取ConcurrentModificationException,但我';我不会搬走的,java,android,concurrency,synchronization,Java,Android,Concurrency,Synchronization,使用此代码,我得到的ConcurrentModificationException是什么?我有一个同步(侦听器)锁 private void notifyListeners(媒体格式副本格式副本){ 如果(格式副本==null)返回; 已同步(侦听器){ for(RenditionEventListener l:侦听器){ if(l.renditionType.equals(rendition.getType())和&l.mediumId==rendition.getMediumId()){ l

使用此代码,我得到的
ConcurrentModificationException
是什么?我有一个同步(侦听器)锁

private void notifyListeners(媒体格式副本格式副本){
如果(格式副本==null)返回;
已同步(侦听器){
for(RenditionEventListener l:侦听器){
if(l.renditionType.equals(rendition.getType())和&l.mediumId==rendition.getMediumId()){
l、 listener.onRendition(格式副本);
}
}
}
}
public void put(字符串格式副本类型、长格式副本、格式副本格式副本){
HashMap l=list.get(格式副本类型);
if(l==null){
l=新的HashMap();
list.put(格式副本类型,l);
}
l、 put(mediumId,格式副本);
通知侦听器(格式副本);
}
public void addRenditionListener(字符串格式副本类型、长mediumId、格式副本侦听器){
已同步(侦听器){
添加(新的格式副本事件监听器(格式副本类型,mediumId,监听器));
}
}
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: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)


解决:显然我是在搬家。请参见下文。

异常表示侦听器可能是从另一个线程修改的。因此,您应该检查它是否正在被修改,而没有在其他地方进行同步


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

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

l.listener.onRendition(rendition);
可能的解决办法如下

  • 使用
    ConcurrentLinkedQueue
    而不是
    ArrayList
    。如果使用此集合,则不需要写入同步块。这是最简单的解决办法
  • 如果1。如果不起作用,可以使用
    CopyOnWriteArrayList
    而不是
    ArrayList
    。在隐藏侦听器时,最好使用
    CopyOnWriteArrayList
    而不是
    ArrayList

  • 不必由其他线程引起。还有什么可以访问侦听器?它也是同步的吗?。。。如果是这样的话,怎么做?“还要检查onRendition()的实现是否将侦听器从列表中删除,因为如果不涉及多个线程,这可能是另一个原因……”是的,就是这样。非常感谢+1指出CopyOnWriteArrayList更适合听众。
    l.listener.onRendition(rendition);