I have a server application which has an ArrayList of connections. This program makes use of multiple threads. The main thread runs a process at intervals to detect closed connections and then remove them from the array so they can be garbage collected.
This process is as follows:
private void cullOtherProcessors() throws Exception {
    //log.log(Level.FINE,"XMLMessageReciever:cullOtherProcessors");
    List<ConnectionAppInterface> toDel = new ArrayList<ConnectionAppInterface>();
    for (ConnectionAppInterface cur : m_OtherProcessors.keySet()) {
        if (cur!=null) {
            if (cur.isClosed()) {
                //Connection is closed - we could never send a message over it
                toDel.add(cur);
            }
        }
    }
    for (int c=0;c<toDel.size();c++) {
        log.log(Level.FINE,"**XMLMessageReciever:cullOtherProcessors - removing closed connection");
        m_OtherProcessors.remove(toDel.get(c));
    }
}
My server ran for a couple of months but according to the logs it crashed with the following error:
08/10/16 01:06:39     calling connect
08/10/16 01:06:39   **XMLMessageReciever:cullOtherProcessors - removing closed connection
08/10/16 01:06:39   CloseableThread: End of run for thread Socket.Connect(113726)
08/10/16 01:06:39     Checking connected
08/10/16 01:06:39     Active Threads this group: 5
08/10/16 01:06:39     getting Message Reciever
08/10/16 01:06:39     Active Threads: 8
08/10/16 01:06:39     Setting m_establishingCon
08/10/16 01:06:39     Establishing connection to robertsNode
Server Failed
java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
    at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
    at metcarob.com.common.network.xmlprotocol.XMLMessageReciever.cullOtherProcessors(XMLMessageReciever.java:57)
    at metcarob.com.common.network.xmlprotocol.XMLMessageReciever.LoopIteration(XMLMessageReciever.java:98)
    at metcarob.com.common.network.xmlprotocol.ConnectionManager.LoopIteration(ConnectionManager.java:48)
    at metcarob.com.personalservices.singlenodeserver.Main.run(Main.java:138)
    at metcarob.com.personalservices.singlenodeserver.Main.main(Main.java:398)
Basically something happened to the ArrayList while I was looping through it (possibly another connection being established) causing nextNode to throw the exception.
I am trying to work out the best method of getting around it. I am considering simply catching and ignoring the error. Any threads missed will simply be culled on the next loop. My proposed solution is:
private void cullOtherProcessors() throws Exception {
    //log.log(Level.FINE,"XMLMessageReciever:cullOtherProcessors");
    //m_OtherProcessors
    List<ConnectionAppInterface> toDel = new ArrayList<ConnectionAppInterface>();
    try {
        for (ConnectionAppInterface cur : m_OtherProcessors.keySet()) {
            if (cur!=null) {
                if (cur.isClosed()) {
                    //Connection is closed - we could never send a message over it
                    toDel.add(cur);
                }
            }
        }
    } catch (ConcurrentModificationException e) {
        log.log(Level.FINE,"**XMLMessageReciever:cullOtherProcessors - ConcurrentModificationException being ignored");
    }
    for (int c=0;c<toDel.size();c++) {
        log.log(Level.FINE,"**XMLMessageReciever:cullOtherProcessors - removing closed connection");
        m_OtherProcessors.remove(toDel.get(c));
    }
}
I will now put this code back into the server and run it for more months.
I would like to know if this is a good solution to the problem. Since it took months for this to occur in the first place and the code loops connections every 5 minutes I think there is a low chance it would occur so often the connections will never be culled. (I will watch the logs and see)
It would be good to know what experts thinks.
**It was suggested this question is the same as "Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop"
It is not. In my code I do not remove items while iterating over the HashMap, instead I iterate over the map and store the items I intend to remove in a temporary Array. I then go through the Array and remove the items.
 
     
     
     
    