这是发送给多个客户端的正确方法吗?

时间:2018-07-13 16:17:48

标签: java

我有一个服务器(线程),该服务器接收数据并具有一组客户端(套接字)。每当客户端连接时,都会创建一个新线程,并将新客户端添加到客户端阵列。

这里是客户:

List<Socket> clients = Collections.synchronizedList(new ArrayList<Socket>());

因此,服务器将接收到的数据发送到客户端,如下所示:

//for each message:
    for(Socket client : clients){ //throws java.util.ConcurrentModificationException
                        new PrintWriter(client.getOutputStream(), true).println(line);
                    }

现在这里有两个问题:

首先,当线程2添加客户端时,我偶尔会遇到java.util.ConcurrentModificationException。

每次发送邮件时,我都会创建一个新的PrintWriter。另一个选择是为每个客户端存储一个PrintWriter,但它是一个客户端,因此没有必要存储PrintWriter

这是一个好方法吗?

2 个答案:

答案 0 :(得分:1)

如果所有客户端都在等待带有getString()的println,这是正确的,否则您可能希望更改为UDP协议。

不必创建新的PrintWriter每个循环,因为连接将保持打开状态,所以最好只有一个(对于每个客户端),而且在客户端,您将只有一个Reader,并且它会等待通过它的消息获取方法。

对于并发问题,您必须创建当前列表的副本:

for (Socket client : new ArrayList<>(clients)) {
   new PrintWriter(client.getOutputStream(), true).println(line);
}

答案 1 :(得分:0)

您正在尝试访问对象(client.getOutputStream()),同时遍历列表java.util.ConcurrentModificationException。将您的List<>更改为ConcurrentLinkedQueue。同样,对于PrintWriter,您只需包装现有流。