問題の背景: サービスの変更についてさまざまなクライアントに通知するクラスがあります。そのため、クラスにリスナーの HashMap がいくつかあり、必要に応じてこれらの HashMap を反復してメソッドを呼び出します (これらの HashMap からリスナーを追加/削除するメソッドもあります)。問題は、反復中に特定のリスナーを削除する必要があることが多いことです...そして、ループの外側から 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();
}}
そして、remove(...) を呼び出したい方法 (およびそれが失敗する方法):
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
これを行うためのトリックはありますか?