当我同时连接超过500个播放器时,我的(多线程)服务器出现这个奇怪的问题,PrinterWriter需要超过100秒或更长时间(2分钟)才能完成flush()或print()。
以下是代码:
public static void send(Player p, String packet)
{
PrintWriter out = p.get_out();
if(out != null && !packet.equals("") && !packet.equals(""+(char)0x00))
{
packet = Crypter.toUtf(packet);
out.print((packet)+(char)0x00);
out.flush();
}
}
printWriter是这样的:
_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_out = new PrintWriter(_socket.getOutputStream());
如果我将关键字synchronized添加到send()方法,则整个服务器开始每2秒延迟一次,如果不这样,那么一些随机播放器会无缘无故地开始滞后。
任何人都有任何想法?这是从哪里来的?我该怎么办?
答案 0 :(得分:1)
打印编写器包裹在套接字的输出流中,所以我猜测并说套接字的输出缓冲区已满,因此写入/刷新调用将阻塞,直到缓冲区有足够的空间容纳消息被送了。
如果数据写入的速度比传输到客户端的速度快(或者比客户端可以接收的速度快),套接字发送缓冲区可能会变满。
修改强>
P.S。如果您遇到可伸缩性问题,可能是因为使用java.io(每个套接字需要一个线程)而不是java.nio(在这种情况下,单个线程可以检测并对那些具有挂起数据的套接字执行操作) 。 nio旨在支持必须扩展到大量连接的应用程序,但编程模型更难。
答案 1 :(得分:0)
原因是你的send()方法是静态的,因此写入任何套接字的所有线程都在包含类对象上进行同步。使其成为非静态的,然后只有同步写入同一套接字的线程才会同步。