I'm creating a multithread chat server in java. When user u1 logs in and sends a message to user u2, if user u2 is not connected the message is sent to the server and put in an ArrayList of pending messages. When user u2 connects, he receive the message from the server and send a message to user u1 as a receipt.
This is my code:
if (pendingmsgs.size()>0) {
for(Iterator<String> itpendingmsgs = pendingmsgs.iterator(); itpendingmsgs.hasNext();) {
//....parsing of the message to get the recipient, sender and text
String pendingmsg = itpendingmsgs.next();
if (protocol.author != null && protocol.author.equals(recipient)) {
response+=msg;
protocol.sendMsg(sender, "Msg "+text+" sent to "+recipient);
itpendingmsgs.remove();
}
}
}
out.write(response.getBytes(), 0, response.length());
This is the ServerProtocol sendMsg() method:
private boolean sendMsg(String recip, String msg) throws IOException {
if (nicks.containsKey(recip)) { //if the recipient is logged in
ClientConnection c = nick.get(recipient); //get the client connection
c.sendMsg(msg); //sends the message
return true;
} else {
/* if the recipient is not logged in I save the message in the pending messages list */
pendingmsgs.add("From: "+nick+" to: "+recip+" text: "+msg);
return false;
}
}
and this is the ClientConnection sendMsg() method:
public void sendMsg(String msg) throws IOException {
out.write(msg.getBytes(), 0, msg.length());
}
where out is an OutputStream.
When user u1 logs in, sends a message to user u2 who is not logged in and then user u1 leaves, when user u2 logs in he doesn't receive the message and I get this exception:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at ChatServer$ClientConnection.run(ChatServer.java:400)
at java.lang.Thread.run(Unknown Source)
Line 400 is
itpendingmsgs.remove();
I've tried using a CopyOnWriteArrayList but it still doesn't work.