Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PrintWriter非常慢的刷新()和打印()。多线程和套接字_Java_Multithreading_Sockets_Printwriter - Fatal编程技术网

Java PrintWriter非常慢的刷新()和打印()。多线程和套接字

Java PrintWriter非常慢的刷新()和打印()。多线程和套接字,java,multithreading,sockets,printwriter,Java,Multithreading,Sockets,Printwriter,我的(多线程)服务器有一个奇怪的问题,当我同时连接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.e

我的(多线程)服务器有一个奇怪的问题,当我同时连接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秒就开始延迟一次,如果我不这样做,那么一些随机播放器就会无缘无故地开始延迟


有人知道吗?这是从哪里来的?我该怎么办?

打印写入程序被一个套接字的输出流所包围,因此我猜测并说套接字的输出缓冲区已满,因此写/刷新调用将被阻塞,直到缓冲区有足够的空间容纳发送的消息

如果向套接字发送缓冲区写入数据的速度快于向客户端发送数据的速度(或快于客户端接收数据的速度),则套接字发送缓冲区可能已满

编辑:


另外,如果您遇到可伸缩性问题,可能是因为使用java.io(每个套接字需要一个线程)而不是java.nio(在这种情况下,单个线程可以检测并在那些具有挂起数据的套接字上执行操作)。nio旨在支持必须扩展到大量连接的应用程序,但编程模型更为困难。

原因是您的send()方法是静态的,因此所有写入任何套接字的线程都在包含的类对象上进行同步。将其设为非静态,则只有写入同一套接字的线程才会被同步。

尽管该方法看起来像是一个不共享任何资源的实用程序方法,因此不需要同步。如果多个调用方可能同时操作一个播放器实例,那么调用方可能应该负责在实用程序方法之外的某些对象(例如播放器实例本身)上进行同步。你说得对!非常感谢。代码太大了,我不得不做很多修改,但是谢谢你。如果只是一个线程问题,我希望它能解决这个问题。也许你是对的。我的默认缓冲区大小是:128000英寸/49152英寸。够了吗?多少就足够了?与其说是缓冲区大小,还不如说是写入套接字的速率,以及客户端传输和接收数据的速率。如果第一个速率大于第二个速率,则调用者将始终阻塞/等待。在这种情况下,您可能试图以过快的速度发送过多的数据;降低更新率或发送的数据量可能会有所帮助。由于您无法控制客户端,因此必须假设任意数量的客户端可能会停止读取或速度慢得令人无法接受。当这种情况发生时,你必须考虑如何处理。如果您的客户端读取数据的速度足够快,您应该能够在10毫秒内刷新到500个连接。i、 e.缓冲器总是有自由空间。你不能让一个慢客户机让其他客户机慢下来。