有地图持有事件监听器通过类型键相同的事件列表不同的线程中删除的项目,可以的CopyOnWriteArrayList帮助允许从已经放在一个迭代器
func_1()
将开始得到一个类型从listenerlist地图并迭代列表以与每个监听者一起处理事件。
当一个监听器完成其处理时,它会要求将其从监听器列表中移除。
由于侦听器处于迭代器中,因此将其从原始列表中删除将导致java.util.ConcurrentModificationException
在iterator.previous()
中获取下一个侦听器。
问题是如果使用CopyOnWriteArrayList来复制监听器列表然后是迭代器,因为它是列表的副本,当监听器从其他线程中被移除时它仍然会抛出?
它只是简单地制作一个正常列表的副本而不是CopyOnWriteArrayList
到迭代器有什么区别?
func_1(Event event) {
List<WeakReference<EventListener<Event>>> listenerlist = mEventMap.get(event.eventType);
/* instead of directly iterator on the listenerlist
ListIterator<WeakReference<EventListener<Event>>> listenerIterator =
listenerlist.listIterator(listenerlist.size());
but making a CopyOnWriteArrayList first:
*/
List<WeakReference<EventListener<Event>>> listeners =
new CopyOnWriteArrayList<>(listenerlist);
ListIterator<WeakReference<EventListener<Event>>> listenerIterator =
listeners.listIterator(listeners.size());
while(listenerIterator.hasPrevious()){
WeakReference<EventListener<Event>> listenerItem =
listenerIterator.previous();
//doing something
listenerItem.func_2(event);
}
}
EventListener::func_2(Event event){
//do something
//remove the type in the map
funct_3(EventListener.this);
}
funct_3(EventListener listener) {
List<WeakReference<EventListener<Event>>> listeners =
mEventMap.get(listener.eventType);
if (listeners != null) {
Iterator<WeakReference<EventListener<Event>>> listenerIterator =
listeners.iterator();
while (listenerIterator.hasNext()) {
WeakReference<EventListener<Event>> listenerItem = listenerIterator.next();
if (listenerItem.get() != null && listenerItem.get() == listener) {
listenerIterator.remove();
break;
}
}
}
}
应该不难测试,但'CopyOnWriteArrayList'保证从不抛出'ConcurrentModificationException'。 – shmosel