Java NIO 在阻塞模式下相对于传统 I/O 的优势?
Posted
技术标签:
【中文标题】Java NIO 在阻塞模式下相对于传统 I/O 的优势?【英文标题】:Advantages of Java NIO in blocking mode versus traditional I/O? 【发布时间】:2011-07-10 12:56:40 【问题描述】:我几乎已经决定不使用异步、非阻塞的 Java NIO。总体而言,复杂性与收益之间的关系非常值得怀疑,我认为在这个项目中特别不值得。
但我读到的关于 NIO 的大部分内容,以及与旧 java.io.* 的比较都集中在非阻塞、异步 NIO 与使用 java.io.* 的每个连接线程同步 I/O 上。但是 NIO 可以用在同步、阻塞、线程一个连接的模式下,这似乎很少讨论。
问题来了:同步阻塞 NIO 与传统同步阻塞 I/O (java.io.*) 相比有什么性能优势吗?两者都是每个连接的线程。复杂度如何比较?
请注意,这是一个普遍的问题,但目前我主要关注 TCP 套接字通信。
【问题讨论】:
+1 表示谨慎 - 复杂性应该是可怕的。 您不能将每个线程连接与阻塞操作一起使用,每个连接需要 2 个线程。 (继续) ...除非你只是在做请求/响应的事情。如果您使用 socket.getInputStream.read() 您将失去直接缓冲区的所有好处,但 impl。仍然使用选择器来阻止读取。我想不出为什么(以及在哪个操作系统上)它应该有好处。 ***.com/a/4752404/32453 提到阻塞模式下的 NIO 更快... 【参考方案1】:它基本上归结为并发连接的数量以及这些连接的繁忙程度。阻塞(每个连接的标准线程)在延迟和吞吐量方面都更快(大约是简单回显服务器的两倍)。因此,如果您的系统可以应对为每个连接维护一个线程(根据经验,
【讨论】:
我同意这取决于您要处理的并发连接数。我的阈值是 100 而不是 1000。1000 个线程对于应用程序来说是很多线程。 (+1) @Michael Barker 为什么每个连接的阻塞线程在延迟和吞吐量方面更快? 不确定,可能是更短/更简单的内核转换。【参考方案2】:NIO 优于“传统”IO 的一个优势是 NIO 可以使用direct buffers,这允许操作系统使用 DMA 进行某些操作(例如,从网络连接直接读取到内存映射文件中),从而避免复制数据到中间缓冲区。
如果您在这种技术确实避免了原本会执行的复制操作的情况下移动大量数据,这可能会对性能产生很大影响。
【讨论】:
+1 NIO 包使用Buffer
s 的系统,而不是InputStream
s 和OutputStream
s(java.io.* 使用的系统)。【参考方案3】:
我不能特别谈论这项技术,但异步库提供同步操作以方便调试的情况并不少见。
例如,如果您遇到问题,您可以消除逻辑的异步部分,而无需重写整个流程。这特别有用,因为同步进程通常更容易使用。
【讨论】:
以上是关于Java NIO 在阻塞模式下相对于传统 I/O 的优势?的主要内容,如果未能解决你的问题,请参考以下文章