所以我在这里阅读我最喜欢的软件模式书之一(面向模式的软件架构 - 并发和网络对象的模式),特别是有关Proactor / Reactor异步IO模式的部分。我可以看到如何通过使用可选择的通道,我可以很容易地实现Reactor风格的异步IO机制(并且已经这样做了)。但是,我无法看到如何使用非阻塞写入实现适当的Proactor机制。这是利用OS管理的非阻塞写入功能。
win32下的操作系统特定调用(如GetQueuedCompletionStatus)支持的功能。
我确实看到Java 7通过异步完成处理程序为NIO带来了一些更新(这似乎是在正确的方向)。话虽如此......鉴于缺乏对操作系统管理的异步操作(特别是异步写入)的统一跨平台支持,我假设这是一个不使用本机操作系统支持的quassy实现。
所以我的问题是,基于proactor的IO处理是否可以在Java中以这样的方式处理,以便用于特定场景;并且,如果Java NIO确实支持基于proactor的IO处理(在Java 6或Java 7中),那么是否使用了OS管理的异步IO支持(即来自OS的完成回调)?此外,如果实现纯粹是在虚拟机中,那么使用主动事件处理的性能优势几乎不会提供构建并发网络处理软件的不同(可能更简单)的方式。
对于对主动事件处理感兴趣的任何人here is a good article,它概述了优点/缺点,并与传统的每个连接线程和反应式IO模型进行了比较。
答案 0 :(得分:22)
这个涉及很多因素。我将尽可能地总结我的发现(意识到关于反应堆和反应器IO处理实施的有用性存在争议)。
是否可以进行基于proactor的IO处理 在Java中以这样的方式 有利于具体使用 场景。
Java 1.4引入了非阻塞IO,它与异步IO不同。 Java SE 7通过JSR203引入了异步IO,使“真正的”proactor样式IO处理实现成为可能。
请参阅AsyncrhonousSocketChannel,AsynchronousServerSocketChannel
并且,如果Java NIO确实支持proactor 基于IO的处理(在Java 6或Java中) Java 7)是OS管理的异步IO 支持(即完成回调 来自OS)被利用?
通过JSR 203规范阅读,肯定支持使用新异步通道的完成处理程序,并且据报道正在使用本机OS功能但我还没有确定到什么程度。在对Java 7源代码进行分析之后,我可能会对此进行跟进(除非有人打败我)。
此外,如果实施是 纯粹是在VM中的表现 使用的好处很少 主动事件处理服务 只不过是一个不同的 (可能更简单)构建方式 并发网络处理软件。
我无法找到有关Java 7中新的异步IO功能的任何性能比较。我相信它们将在不久的将来上市。
与往常一样,当提出解决问题的方法不止一种时,哪种方法更好的问题几乎总是以“依赖”来回答。 Java 7中包含主动事件处理(使用异步完成处理程序),并且不能无目的地存在。对于某些应用程序,使用此类IO处理是有意义的。历史上,在proactor具有良好适用性的情况下给出的一个常见示例是在HTTP服务器中,其中经常发出许多短请求。有关更深入的解释give this a read(仅用于突出显示proactor的优点,因此请忽略示例代码为C ++的事实)。
IMO似乎很明显,在许多情况下,反应器/反应器使使用更传统方法的非常简单的设计复杂化,而在其他更复杂的系统中,它们提供了高度的简化和灵活性。
。 。
另外,我强烈建议您阅读the following presentation about NIO,其中提供了NIO与“传统”方法之间的性能比较。虽然我也建议谨慎对待所提供的结果,因为基准测试中的NIO实现基于Java 1.4 NBIO NIO库而不是1.4中提供的NIO实现。
答案 1 :(得分:7)
我会检查你真的需要担心阻止写入。
没有要读取数据的读取块。这可能是大部分时间。但是,当缓冲区已满时写入会发生阻塞,这种情况很少发生,并且通常表示连接速度较慢或消费者失败。
如果您想要非阻塞IO,请为读取执行此操作,并为此进行写入。
注意:对NIO使用阻塞IO通常更简单并且可以执行非阻塞NIO,除非您有1000个连接,您可能会发现添加的复杂性是不值得的。 (可能不是最好的选择)
答案 2 :(得分:2)
我最喜欢的软件模式之一 书籍(面向模式的软件 架构 - 并发模式 和网络对象)
尊重这本书非常过时,并且在任何时候都具有可疑的相关性。它源于20世纪90年代后期的设计模式狂热,当时人们齐心协力将整个计算机科学简化为设计模式。
我现在的观点是,NIO已经是一个框架和设计模式。
答案 3 :(得分:1)
NIO已经提供了反应模式(选择器)和NIO2 adds an implementation of the proactive pattern(完成处理程序)的实现。
不要重新发明它,只是使用它,因为你无法击败它的性能 - 这是任何试图避免阻止i / o的人毕竟 - 用纯Java解决方案,因为你没有' t可以访问底层操作系统的非阻塞/异步功能。但是NIO和NIO2使用它们,这使它们变得快速。