This discussion is archived
2 Replies Latest reply: Jan 4, 2005 2:58 PM by 807596 RSS

ConcurrentModificationException......err....

807596 Newbie
Currently Being Moderated
Hey all,

I am writing a stream based server program, which at the moment just allows people to talk to each other. I'm now writing the command parser that will parse client commands on the server.....things like "/QUIT".
This is interpreted correctly, but I have a small problem......the client manager thread works by iterating through the list of currently connected users and processing requests like this: -
// Thread run method.
    public void run() {
        String sMessage;
        ClientConnection c;
        Iterator iterator;
        
        do {
             iterator = listClients.iterator();
             while (iterator.hasNext()) {
                  String statusMessage;
                  c = (ClientConnection)iterator.next();
                  sMessage = c.getMessage();
                  if (sMessage != null) {
                       c.clearMessageBuffer();
                       // Check to see if the first character ('/') denotes a command.
                       if (sMessage.trim().indexOf("/") != -1) {
                            // Pass the message and the current client to the command parser. 
                            commandParser.parseCommandString(sMessage, c);
                       } else {
                            // Message received to be sent to all connected clients.
                                        // Display on server screen first. 
                            pOutput.printOutput(c.getNick() + ": " + sMessage);
                                        // Broadcast to all clients. 
                            broadcastString(c.getNick() + ": " + sMessage);
                       }
                  } 
             }
        } while (bThreadActive);
        stopClientManager();
    }
When the command parser detects the "/QUIT" string, it removes the client from the current list of users.......which immediately brought up a ConcurrentModificationException...which is a new one on me. So I dig around the docs and come up with this: -

"...it is not generally permssible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances."

Okay.....so I'm having a problem modifying the collection as I'm iterating through it......this is because the client connection object is removed from the list when the user quits, which I guess messes up the call to next().
My first thought was "thats okay, I'll just break out of the loop this time round after modifying the user list and the server will catch any unsend messages next iteration". Problem is, if I do that, this effectively brings execution to the end of the run() method and shuts down the client manager.

I'm thinking that I should have a loop within a loop or something, so the jumping the iteration and recalling .next() doesn't throw this exception and instead just goes back into the iterator loop while NOT breaking out of the threadActive while loop.

I'm having a nagging feeling I'm missing something here, so does anyone have any advice? Is the structure of my run() method flawed to allow this to happen in the first place?

Thanks for any info.