我正在编写多线程套接字服务器。我用的是nio的 ServerSocketChannel 用于接受连接。然后我正在读取和写入(在单独的线程中) socketChannel 使用 bufferedreader 和印刷作家。问题是 PrintWriter 锁定并等待 flush() 命令。它会阻塞线程直到 BufferedReader 接收数据。

有帮助吗?

解决方案

这表明接收器正在缓慢读取。这就是阻塞 I/O 的工作原理。如果您想要非阻塞 I/O,那么您已经成功了,因为您已经在使用 NIO。虽然我真的完全看不出在阻塞模式下使用 NIO 的意义。

其他提示

正如 @EJP 所说,这基本上就是阻塞 IO 的工作方式。事实上,这个问题是任何拥有生产者和消费者的架构所固有的。如果生产者生产内容(在本例中为文本输出行)的速度比消费者消费它的速度快,那么生产者最终必须阻塞。


你怎么解决这个问题?首先是一些一般性的东西。

如果生产者生产东西的速度比消费者消费它的速度快 从长远来看, ,你进退两难。您必须降低生产者的生产速度,加快消费者的消费速度,或者减少管道中的开销以达到相同的效果。其他都不起作用。

如果速率不匹配只是暂时的,您可以通过向管道添加一些额外的缓冲来“掩盖裂缝”。如果之间的连接具有一定的缓冲能力,您也许可以增加它。或者,您可以在生产者或消费者端添加额外的缓冲。


以下是一些可能对您的特定情况有帮助的事情。

  • 减少在生产者线程中编写的内容量。

  • 在消费者线程中减少工作量,或者分析/调整它们以更快地完成工作。

  • 不要使用套接字在同一 JVM 中的两个线程之间进行通信。如果您可以安排它,请使用 Java PipeInputStream / PipeOutputStream 对,或推出您自己的等效项。(如果使用套接字,则读取和写入涉及系统调用、将数据复制到内核缓冲区或从内核缓冲区复制数据等等。)

  • 在通信的情况下 不得不 走出 JVM,确保使用 Buffered* 底层流的包装器,以减少读/写时进行的系统调用的数量。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top