문제의 배경 : 다양한 클라이언트에게 서비스 변경 사항을 알리는 책임이있는 클래스가 있습니다. 따라서 클래스에는 여러 청취자의 HashMap이 있고 필요한 경우 해당 HashMaps를 반복하여 메서드를 호출합니다 (해당 HashMaps에서 청취자를 추가/제거하는 메서드도 있음). 문제는 반복되는 동안 특정 리스너를 제거해야한다는 것입니다 ... 그리고 루프 외부에서 remove (...) 메서드를 호출 할 수 있어야합니다.동일한 스레드에서 반복 및 제거가 모두 발생합니다. 클래스의 예 :반복자를 사용하지 않고 HashMap에서 항목을 동시에 수정/제거
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
이 작업을 수행하기 위해 어떤 트릭이 있습니까?
네, 작동합니다. 그건 그렇고, 언제 제거가 일어나고 있습니까? 전화가 오면 ** ** a ** 항목이 제거되었는지 확인할 수 있습니까? –
제거는 실시간으로 발생하지만 컬렉션의 스냅 샷에서 반복이 발생합니다. @finejustice가 공유하는 문서를 읽으십시오. 도움이 될거야 :) – vineet