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

Java 这是发送到多个客户端的正确方法吗?,java,Java,我有一个服务器(线程),它接收数据,并有一组客户端(套接字)。每当客户机连接时,都会创建一个新线程,并将一个新客户机添加到客户机阵列中 以下是客户: List<Socket> clients = Collections.synchronizedList(new ArrayList<Socket>()); 现在这里有两个问题: 首先,当线程2添加客户机时,我偶尔会得到一个java.util.ConcurrentModificationException 此外,每次发送邮件

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

以下是客户:

List<Socket> clients = Collections.synchronizedList(new ArrayList<Socket>());
现在这里有两个问题:

首先,当线程2添加客户机时,我偶尔会得到一个java.util.ConcurrentModificationException

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


这是一种好方法吗?

如果所有客户端都在等待一个带有getString()的println,那么这是正确的,否则您可能需要更改为UDP协议


创建一个新的PrintWriter EveryLop是不必要的,因为连接将保持打开状态,因此最好只有一个(对于每个客户端),而且在客户端,您将只有一个读卡器,并且该读卡器将通过其get方法等待消息

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

for (Socket client : new ArrayList<>(clients)) {
   new PrintWriter(client.getOutputStream(), true).println(line);
}
for(套接字客户端:新ArrayList(客户端)){
新的PrintWriter(client.getOutputStream(),true).println(行);
}

您试图访问一个对象(
client.getOutputStream()
),同时在列表上进行迭代,从而访问
java.util.ConcurrentModificationException
。更改
ConcurrentLinkedQueue的
列表
。同样对于
PrintWriter
,这里您只需包装一个现有流

“不需要创建一个新的PrintWriter EveryLop”,因此您建议为每个客户端存储一个PrintWriter?没错,通常使用多客户端的方法也是为每个客户端都有一个单独的线程(这样在向一个客户端写入时就不会阻塞其他客户端)目前,我有一个新线程,用于侦听新客户机并将其添加到阵列中。之后,另一台服务器接管并在阵列中循环。听起来不错不?它很有效。。。但是想象一下,有一百万个客户机,您将让每个客户机等待循环完成,以接收新消息
for (Socket client : new ArrayList<>(clients)) {
   new PrintWriter(client.getOutputStream(), true).println(line);
}