Java – How can I safely remove a handler from a callback when iterating through the event handler collection?

How can I safely remove a handler from a callback when iterating through the event handler collection?… here is a solution to the problem.

How can I safely remove a handler from a callback when iterating through the event handler collection?

I’m a little confused about something. Java’s documentation tells us that there is no defined behavior when removing items from the collection when iterating over the collection using the Iterator object, and the only safe way is to use Iterator.remove().

So if, while traversing the list, one of the handlers decides it’s time to remove itself as a listener, how do you safely remove an event handler from the ArrayList?

// in public class Dispatcher

public void dispatchEvent(){
    Iterator<IEventHandler> iterator = mHandlers.iterator();
    IEventHandler handler = null;
    while(iterator.hasNext()){
        handler = iterator.next();
        handler.onCallbackEvent();
    }
}

public void insertHandler(IEventHandler h){
    mHandlers.add(h);
}

public void removeHandler(IEventHandler h){
    mHandlers.remove(h);
}

At the same time, the handler is instantiated like this….

final Dispatcher d = new Dispatcher();
d.insertHandler(new IEventHandler(){
    @Override
    public void onCallbackEvent(){
        Log.i(" callback happened ");
        d.removeHandler(this);
    }
});

See a potential problem? As a result of the onCallbackEvent() declared in a particular handler, you are removing the handler from the ArrayList while you are still iterating using the iterator.

Is this a tricky question? What is the safe way to handle this situation?

Solution

This is a very common problem when implementing an event system. The only solution is to copy the list of handlers on change. You can do this yourself in the insertHandler/removeHandler method, or just use CopyOnWriteArrayList.

Related Problems and Solutions