问题的一些背景:我有一个班,负责通知各个客户有关服务的变化。因此,该类有几个HashMaps的侦听器,并在需要时通过迭代这些HashMaps来调用它们的方法(它还有从这些HashMaps添加/删除侦听器的方法)。问题是我经常需要在迭代时删除某些侦听器...... 我需要能够从循环外部调用remove(...)方法。 两者都在迭代和删除发生在同一个线程上。类的例子:
class SomeClass {
Map<Listener, Boolean> listeners = new HashMap<Listener, Boolean>();
void add(Listener listener) {
listeners.put(listener, true);
}
void remove(Listener listener) {
listeners.remove(listener);
}
void notifyListeners() {
Iterator<Map.Entry<Listener, Boolean>> it = listeners.entrySet().iterator();
while (it.hasNext()) {
it.next().getKey().onDo();
}
}
static interface Listener{
void onDo();
}}
我想要调用的方式删除(...)(以及失败的方式):
final SomeClass someClass = new SomeClass();
Listener a = new Listener(){
@Override
public void onDo() {
someClass.remove(this);
}
};
Listener b = new Listener(){
@Override
public void onDo() {
someClass.remove(this);
}
};
Listener c = new Listener(){
@Override
public void onDo() {
someClass.remove(this);
}
};
someClass.add(a);
someClass.add(b);
someClass.add(c);
someClass.notifyListeners();
// java.util.ConcurrentModificationException
有没有诀窍呢?
答案 0 :(得分:2)
您是否尝试过ConcurrentHashMap?
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html
答案 1 :(得分:1)
您的问题是使用ConcurrentHashMap
的候选人。只需将地图定义替换为ConcurrentHashMap
Map<Listener, Boolean> listeners = new ConcurrentHashMap<Listener, Boolean>();