Java でマルチスレッド チャット サーバーを作成しています。ユーザー u1 がログインしてユーザー u2 にメッセージを送信すると、ユーザー u2 が接続されていない場合、メッセージはサーバーに送信され、保留中のメッセージの ArrayList に入れられます。ユーザー u2 が接続すると、サーバーからメッセージを受信し、受信メッセージとしてユーザー u1 にメッセージを送信します。
これは私のコードです:
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());
これは ServerProtocol sendMsg() メソッドです。
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;
}
}
これは ClientConnection の sendMsg() メソッドです。
public void sendMsg(String msg) throws IOException {
out.write(msg.getBytes(), 0, msg.length());
}
out は OutputStream です。
ユーザー u1 がログインすると、ログインしていないユーザー u2 にメッセージが送信され、ユーザー u1 が去ります。ユーザー u2 がログインすると、メッセージが受信されず、次の例外が発生します。
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)
400行目は
itpendingmsgs.remove();
CopyOnWriteArrayList を使用してみましたが、まだ機能しません。