PrintWriter 等待flush()
-
15-11-2019 - |
题
我正在编写多线程套接字服务器。我用的是nio的 ServerSocketChannel
用于接受连接。然后我正在读取和写入(在单独的线程中) socketChannel
使用 bufferedreader
和印刷作家。问题是 PrintWriter
锁定并等待 flush()
命令。它会阻塞线程直到 BufferedReader
接收数据。
解决方案
这表明接收器正在缓慢读取。这就是阻塞 I/O 的工作原理。如果您想要非阻塞 I/O,那么您已经成功了,因为您已经在使用 NIO。虽然我真的完全看不出在阻塞模式下使用 NIO 的意义。
其他提示
正如 @EJP 所说,这基本上就是阻塞 IO 的工作方式。事实上,这个问题是任何拥有生产者和消费者的架构所固有的。如果生产者生产内容(在本例中为文本输出行)的速度比消费者消费它的速度快,那么生产者最终必须阻塞。
你怎么解决这个问题?首先是一些一般性的东西。
如果生产者生产东西的速度比消费者消费它的速度快 从长远来看, ,你进退两难。您必须降低生产者的生产速度,加快消费者的消费速度,或者减少管道中的开销以达到相同的效果。其他都不起作用。
如果速率不匹配只是暂时的,您可以通过向管道添加一些额外的缓冲来“掩盖裂缝”。如果之间的连接具有一定的缓冲能力,您也许可以增加它。或者,您可以在生产者或消费者端添加额外的缓冲。
以下是一些可能对您的特定情况有帮助的事情。
减少在生产者线程中编写的内容量。
在消费者线程中减少工作量,或者分析/调整它们以更快地完成工作。
不要使用套接字在同一 JVM 中的两个线程之间进行通信。如果您可以安排它,请使用 Java PipeInputStream / PipeOutputStream 对,或推出您自己的等效项。(如果使用套接字,则读取和写入涉及系统调用、将数据复制到内核缓冲区或从内核缓冲区复制数据等等。)
在通信的情况下 不得不 走出 JVM,确保使用
Buffered*
底层流的包装器,以减少读/写时进行的系统调用的数量。