Question

Some background to the problem: I have a class which is responsible for informing various clients about changes in service. So it the class has several HashMaps of listeners and calls their methods by iterating those HashMaps when needed (it also has methods to add/remove listeners from those HashMaps). The problem is that often I need remove certain listeners while they are being iterated... and I need to be able to call remove(...) method from outside the loop. Both iterating and removing are happening on the same thread. Example of the class:

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();
    }}

And the way I want to call remove(...) (and how that fails):

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

Is there any trick to do this?

Was it helpful?

OTHER TIPS

Your problem is candidate for using ConcurrentHashMap. Just replace your map definition to ConcurrentHashMap

Map<Listener, Boolean> listeners = new ConcurrentHashMap<Listener, Boolean>();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top