我正在编写多线程套接字服务器。我使用nio的ServerSocketChannel
来接受连接。然后我使用socketChannel
和打印作者在bufferedreader
上阅读和写作(在单独的主题中)。
问题是PrintWriter
锁定并等待flush()
命令。它会阻塞线程,直到BufferedReader
接收数据。
答案 0 :(得分:2)
这表明接收器读取速度很慢。这就是阻止I / O工作的方式。如果你想要非阻塞I / O,那么你就已经在那里了,因为你已经在使用NIO了。虽然我真的没有看到在阻止模式下使用NIO的意义。
答案 1 :(得分:0)
正如@EJP所说,这基本上就是阻止IO工作的方式。实际上,这个问题在您拥有生产者和消费者的任何体系结构中都是固有的。如果生产者生成的东西(在这种情况下是文本输出行)比消费者可以消耗它更快,那么生产者最终必须阻止。
你怎么解决这个问题?首先是一些一般的东西。
如果生产者生产的东西比消费者长期消耗的东西更快,那么你就是在摇滚和硬地之间。您必须降低生产者的生产率,加快消费者的消费率,或者减少管道中的管理费用以达到同样的效果。没有别的办法。
如果速率不匹配只是暂时的,您可以通过在管道中添加一些额外的缓冲来“克服裂缝”。如果它们之间的连接具有一些缓冲功能,您可以增加它。或者,您可以在生产者或消费者端添加额外的缓冲。
以下是一些可能对您的特定情况有所帮助的事情。
减少您在生产者线程中写入的内容。
在消费者线程中减少工作量,或对其进行分析/调整以更快地完成工作。
不要使用套接字在同一JVM中的两个线程之间进行通信。如果您可以安排它,请使用Java PipeInputStream / PipeOutputStream对,或者滚动您自己的等效项。 (如果使用套接字,则读取和写入涉及系统调用,将数据复制到内核缓冲区中等等。)
如果通信必须移出JVM,请确保为基础流使用Buffered*
包装器,以减少读取时发出的系统调用次数/ 写作。